【B站 heima】小兔鲜Vue3 项目学习笔记

系列文章目录

Day 01

目录

  • 系列文章目录
    • 前言
    • Day01
      • 1.项目使用相关技术栈
      • 2. 项目规模和亮点
      • 3. Vue2和Vue3实现一个小案例
      • 4. vue3的优势
      • 5. create-vue脚手架工具
      • 6. 熟悉我们的项目目录和文件
      • 7. 组合式API-setup选项
      • 8. 组合式API-reactive和ref函数
      • 9. 组合式API-computed计算属性
      • 10. 组合式API-watch监听属性
      • 11. 组合式API-生命周期函数
      • 12. 组合式API-父子通信
      • 13. 组合式API-子传父
      • 14.组合式API-模板引用
      • 15.组合式API-provide和inject
      • 16.综合小案例
        • 渲染
        • 删除
        • 编辑
    • Day01小结

前言

vue3现在使用很广泛,必学!

vue3项目,本文主要是学习项目功能实现并进行总结。

配套资料的话去B站下方自己拿。

持续更新…

Day01

1.项目使用相关技术栈

create-vue、Vue3+Setup、VueRouter、VueUse、Pinia

知识点插入:

C端:C是单词Consumer的缩写,即个人用户。C端产品指的是面向个人用户的产品,如微信、淘宝。

B端:B是单词Business的缩写,即企业用户。B端产品指的是面向企业用户的产品,如ERP系统、CRM系统。

2. 项目规模和亮点

项目规模:涉及到9大业务模块,27+业务组件、20+业务接口、10+业务解决方案

项目亮点:长页面吸顶交互实现、图片懒加载指令封装、画板插槽组件等业务通用组件封装、SKU电商组件封装、通用逻辑函数封装、路由缓存问题处理。

3. Vue2和Vue3实现一个小案例

需求描述:点击按钮,数字+1

vue2实现:

//vue2 选项式API
<template>
    <button @click="addCounter">{{ counter }}</button>
</template>

<script>
export default {
    name: 'Counter',
    data() {
        return {
            counter: 0
        }
    },
    methods: {
        addCounter() {
            this.counter++;
        }
    }
}
</script>

vue3实现:

//vue3 组合式API
<template>
    <button @click="addCounter">{{ counter }}</button>
</template>

<script setup>
//有这个setup就可以写组合式api了
import { ref } from 'vue'  //ref 生成响应数据
const counter = ref(0)
const addCounter = () => { counter.value++ }
</script>

vue3的代码量变少了,分散式维护编程了集中式维护了

4. vue3的优势

  • 组合式API,能更好的支持TS,容易维护
  • 速度提高,diff算法重写,模板编译优化,组件初始化更高效了
  • 按需引入,良好的treeShaking,体积更小
  • 数据响应式更优了,proxy

5. create-vue脚手架工具

我们之前在vue2学过使用过vue-cli脚手架

vue3使用的是create-vue,底层是vite,我们使用它来创建项目。

创建环境条件:node.js版本16.0以上

创建vue3应用,安装并执行create-vuenpm init vue@latest

注:目前配置项我们都是否,做项目的时候按需选择。在这里插入图片描述

这样我们就安装成功了,按照它的绿色代码执行(进入文件夹,安装依赖,运行项目),将我们的代码运行起来
在这里插入图片描述
运行起来地址,我们打开:
在这里插入图片描述

如果是这个页面就是成功的,这个页面也是一个很好的学习工具,感兴趣可以点击了解一下:
在这里插入图片描述

6. 熟悉我们的项目目录和文件

package.json:本次项目执行的命令和相关的依赖。
在这里插入图片描述
vite.config.js:项目配置文件,在vue2中是vue.config.js
在这里插入图片描述

业务文件夹src下的main.js入口文件

//入口文件
//vue2中式new Vue()创建一个应用实例对象
//vue3中使用createApp函数创建应用实例
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'

//1.以App为参数,生成一个应用实例对象
//2.挂载到id为app的节点上
createApp(App).mount('#app')

这个节点在哪呢,和vue2一样在index.html

在这里插入图片描述

src中的App.vue

我删了一些代码,结构看起来更清晰

<script setup>
<!--setup:开关,容许在script中书写组合式API-->
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>

<template>
  <header>
    <img  />
    <div class="wrapper"></div>
  </header>
  <main>
    <TheWelcome />
  </main>
</template>

<style scoped>
...
</style>

相比于vue2scripttemplate顺序发生了改变,template里不再要求唯一根元素,省去了一些无用的元素。

7. 组合式API-setup选项

我们先看一些组合式api和选项式api是什么

  • 组合式API是一种基于函数的API,它允许开发者将组件的逻辑代码拆分成多个独立的函数,每个函数负责处理特定的功能或逻辑。

  • 选项式API是基于对象的,我们将一个Vue实例的各个部分拆分成不同的选项,如data、methods、computed、watch等,并在创建Vue实例时将它们作为选项传入。

setup的写法:

<script>
export default {
  setup() {
   ...
  }
}
</script>

这个函数会在生命周期beforeCreate之前执行,验证一下:

<!--App.vue-->
<script>
export default {
  setup() {
    console.log('setup')
  },
  beforeCreate() {
    console.log('beforeCreate')
  }
}
</script>
<template>

</template>
<style></style>

在这里插入图片描述

setup的用法:

  • 在setup定义数据和函数
  • setup函数中 return 数据和函数
  • 在template中使用数据和方法

做个小练习:

<script>
export default {
  setup() {
    //1.声明变量和函数
    const message = '我是一个小蘑菇'
    const logMessage = () => {
      console.log(message)
    }
    return {
      //2.返回变量和函数
      message,
      logMessage
    }
  },
}
</script>
<template>
  //3.使用变量和函数
  {{ message }}
  <button @click="logMessage">点击我</button>
</template>
<style></style>

保存,看效果:

在这里插入图片描述

这里不再推荐使用this,this也获取不到组件实例对象了

这里vue3提供了一个语法糖<script setup>,可以简化代码的写法,将export default、setup()、return都简化掉了

刚才那个栗子使用语法糖的写法:

<script setup>
    const message = '我是一个小蘑菇'
    const logMessage = () => {
      console.log(message)
    }
</script>
<template>
  {{ message }}
  <button @click="logMessage">点击我</button>
</template>

8. 组合式API-reactive和ref函数

作用:生成响应数据

响应式数据:数据变而页面变

reactive:传入对象类型数据,返回一个响应式对象,注意是对象类型

reactive用法:

  • 导入reactive
  • 执行函数(传参,接收)
<script setup>
//引入
import { reactive } from 'vue';
//对象类型变量
const person = {
  name: 'ruru',
  age: 18
}
//使用函数
const res = reactive(person);

</script>
<template>
  <!-- 使用变量 -->
  我是{{ res.name }},我今年{{ res.age }}岁了
  <button @click="res.age++">年龄+1</button>
</template>

在这里插入图片描述

ref:传入简单或对象类型数据,返回一个响应式对象,简单类型和对象类型都支持

ref用法:

  • 导入ref
  • 执行函数(传参,接收)

注意:脚本区域修改ref产生的响应式对象数据(如 a),需要通过value属性。

<script setup>
//引入
import { ref } from 'vue';
//对象类型变量
const name = 'ruru'
const age = 18
const add = () => {
  a.value++
}
//使用函数
const n = ref(name);
const a = ref(age)

</script>
<template>
  <!-- 使用变量 -->
  我是{{ n }},我今年{{ a }}岁了
  <button @click="add">点击a+1</button>
</template>

在这里插入图片描述

ref函数内部实现依赖于reactive,实际工作中推荐使用ref函数,比较灵活

9. 组合式API-computed计算属性

思想和vue2保持一致,只是写法不同

用法:

  • 导入
  • 执行函数,return计算之后的值,变量接收

小栗子实现:[1,2,3,4,5,6,7,8] =》 [3,4,5,6,7,8]

<script setup>
import { computed, ref } from 'vue';
const arr = ref([1, 2, 3, 4, 5, 6, 7, 8]);
const arr2 = computed(() => {
  //ref产生的数据要通过value修改,使用filter函数过滤
  return arr.value.filter(item => item > 2)
})
</script>

<template>
  <div>
    原始响应式数组:{{ arr }}
	<br />
    过滤后的数组:{{ arr2 }}
  </div>
</template>

****

计算属性中不应该有副作用,避免直接修改计算属性的值,计算属性应该是只读

10. 组合式API-watch监听属性

侦听一个或者多个数据的变化,数据变化时执行监听函数

额外参数:immediate(立即执行)、deep(深度监听)

使用:

  • 导入函数
  • 执行watch函数,参数传入响应式数据回调函数

举个 单个数据 的栗子

<script setup>
import { watch, ref } from 'vue';
const count = ref(0)
const setCount = () => {
  count.value++
}
//监听属性watch
watch(count, (newValue, oldValue) => {
    //当count发生改变时打印
  console.log('count改变了',newValue, oldValue)
  
})

</script>

<template>
  <div>
    当前count:{{ count }}
    <button @click="setCount">count+1</button>
  </div>
</template>

在这里插入图片描述

监听 多个数据 的话,只需要改动一下参数,参考代码⬇

多个数据中,只要有一个数据改变了,就会调用回调函数。

watch(
[count,name],
([newCount,newName],[oldCount.oldName]) =>{
	...
	}
)

immediate:侦听器创建时立即触发回调,响应式数据变化继续执行回调

用法示例:

const count = ref(0)
watch(count,()=>{
	console.log('count发生了变化')
},{
immediate : true
})

通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项

deep:深层监听

const state = ref({count:0})
watch(count,()=>{
    //count发生变化也不会打印
	console.log('count发生了变化')
})
const state = ref({count:0})
watch(count,()=>{
    //会打印
	console.log('count发生了变化')
},{
    deep:true
})

精确监听

假如目前有两个响应式数据agename,我只想在监听到age数据变化的时候执行回调函数,该怎么办呢?

我们可以这样做:watch参数写两个回调,一个写数据值,另一个写逻辑,大致代码如下:

const person = ref({name:'ruru',age:18})
watch(
	()=>person.age.value,
    ()=> console.log('age改变了')
)

deep有性能损耗,尽量不开启deep,使用 精确监听

11. 组合式API-生命周期函数

vue2和vue3生命周期API(选项式 vs 组合式)

选项式API组合式API
beforeCreate/createdsetupvue3无onCreated钩子,直接写在setup中即可。
beforeMountonBeforeMount挂载之前
mountedonMounted挂载完毕
beforeUpdateonBoforeUpdate更新之前
UpdatedonUpdated更新完毕
beforeUnmountonBeforeUnmount销毁之前
unmountedonUnmounted销毁完毕

基本使用:

  • 导入
  • 执行函数,传入回调

我们以onMounted作栗子来演示生命钩子的使用。

<script setup>
import { onMounted, ref } from 'vue';

onMounted(() => {
  console.log('组件挂载完毕')
})

</script>

<template>
</template>

生命周期函数可执行多次,按顺序执行

一种适用场景是:当你拿到一个写好的项目,不敢改别人的代码怕给整错了,就可以创建一个钩子写入自己的代码,不会影响别人的代码。

<script setup>
import { onMounted, ref } from 'vue';
onMounted(() => {
  console.log('组件挂载完毕1')
})
onMounted(() => {
  console.log('组件挂载完毕3')
})
onMounted(() => {
  console.log('组件挂载完毕2')
})


</script>

<template>
  <div>

  </div>
</template>

在这里插入图片描述

12. 组合式API-父子通信

最常用,最简单

基本思想:

  • 父组件给子组件绑定属性
  • 子组件通过defineProps编译器宏,接收子组件传递过来的数据

现在我们准备了父App.vue和子son.vue组件。

子组件导入父组件之后,不需要注册直接使用,这是setup语法糖的一个效果。

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'

</script>

<template>
  <div>
    <h2>父组件App</h2>
    <Son />
  </div>
</template>
<!-- son.vue -->
<script setup>

</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
    </div>
</template>

效果:
在这里插入图片描述

现在我们要实现数据的传递:

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'

</script>

<template>
  <div>
    <h2>父组件App</h2>
    <!-- 1.属性绑定 -->
    <Son message='我是父组件的数据' />
  </div>
</template>
<!-- son.vue -->
<script setup>
const props = defineProps({
    // 2.接收
    message: String
})
</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
        <!-- 3.使用 -->
        {{ message }}
    </div>
</template>

上述代码使用了props变量接收了数据,我们可以props.message获取到数据。

补充:

传入响应式数据,传递多个数据,相关代码演示:

// App.vue 
const count = ref(0)

<Son :count="count" message = '我是父组件的数据' />
//son.vue 
const props = defineProps({
	message:String,
	count:Number
})

13. 组合式API-子传父

基本思想:

  • 父组件给子组件标签通过@绑定事件

  • 子组件通过defineEmits编译器生成emit方法

  • 触发自定义事件,传递参数

通过栗子演示

<!-- App.vue -->
<script setup>
import { onMounted, ref } from 'vue';
import Son from '@/components/son.vue'
const getMessage = (msg) => {
  console.log(msg)
}
</script>

<template>
  <div>
    <h2>父组件App</h2>
    <!--1.绑定事件  -->
    <Son @get-message="getMessage" />
  </div>
</template>
<!-- son.vue -->
<script setup>
//2.生成emit方法
const emit = defineEmits(['get-message'])
//3.触发自定义事件,传参 
const sendMsg = () => emit('get-message', '我是来自子组件的信息,收到请回答!')
</script>
<template>
    <div class="son">
        <h3>子组件son</h3>
        <!-- 4.使用 -->
        <button @click="sendMsg">给父组件发信息</button>
    </div>
</template>

在这里插入图片描述

14.组合式API-模板引用

学过vue2的应该很熟悉

通过ref获取真实的dom对象或者组件示例对象。

获取dom使用方法(组件同理):

  • 调用 ref 函数生成一个 ref 对象
  • 通过 ref 标识绑定 ref 对象到标签
  • 通过value获取标签
<script setup>
import {ref} from 'vue'
//1.调用ref函数
const h1ref = ref(null)

//组件挂载完毕才能获取到dom对象
onMounted(()=>{
    console.log(h1ref.value)  //<h1>我是dom标签h1</h1>
})
</script>
<template>
<!--2.通过ref标识绑定ref对象-->
<h1 ref="h1ref">我是dom标签h1</h1>
</template>

defineExpose:

默认情况下,在<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性可以访问。

<script setup>
import {ref} from 'vue'
const msg = ref('一段消息')
defineExpose({
    msg
})
</script>

15.组合式API-provide和inject

顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信。

在这里插入图片描述

实现办法:

  • 从vue中引入这俩函数

  • 顶层数据通过provide函数提供数据/响应式数据

provide('key',顶层数据/ref对象)
  • 底层组件通过inject函数获取数据
const message = inject('key')

除了可以传数据,还可以传方法

  • 从vue中引入这俩函数

  • 顶层数据通过provide函数提供函数

const setCount = ()=>{
    count.value++
}
provide('setCount-key',setCount)
  • 底层组件通过inject函数获取函数
const setCount = inject('setCount-key')
  • 就可以在底层组件中使用了
<button @click="setCount">修改顶层组件的count</button>

底层函数想要通知顶层函数组件做修改的话,传递一个方法,底层函数调用方法·

16.综合小案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

找个文件夹,克隆一下,阅读README.md

安装依赖,启动项目:

npm install
npm run dev

页面就是这样的啦:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们是要实现:渲染、编辑、删除 三个小功能

渲染

思路:声明响应式列表list - 调接口获取数据赋值给list - 绑定给table

const list = ref([])
const getList = async () => {
  const res = await axios.get('/list')
  list.value = res.data  //赋值
}
 <el-table :data=list>
     ...
</el-table>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

删除

思路:获取当前行的id - 调用接口 - 更新数据

<!--利用插槽-->
<template #default="{ row }">
          <el-button type="primary" link>编辑</el-button>
          <el-button type="danger" link @click="delList(row.id)">删除</el-button>
        </template>
const delList = async (id) => {
  await axios.delete(`/del/${id}`)
  getList()
}
编辑

思路:打开弹框 - 回填数据 - 更新数据

点击 编辑 按钮,打开弹框

<el-button type="primary" link @click="onEdit">编辑</el-button>

父组件获取子组件的数据dialogVisible,使用ref获取子组件的示例对象,调用其方法或者属性

const editRef = ref(null)

<Edit ref="editRef" />
const open = ()=>{
	dialogVisible.value = true
}
defineExpose({
    open
})
const onEdit = ()=>{
	editRef.value.open()
}

这时弹框可以正常打开了。

我们在点击按钮调用onEdit,将数据给Edit组件传下去

<el-button type="primary" link @click="onEdit(row)">编辑</el-button>
const onEdit = (row)=>{
	editRef.value.open(row)
}
const open = (row)=>{
	dialogVisible.value = true
	console.log(row)
}

这样子组件就拿到了数据

准备一个Edit组件的响应式数据form,用来绑定数据

这个属性名称要参考下面的姓名和籍贯书写

const form = ref({
	name:'',
	place:''
})
const open = (row)=>{
	dialogVisible.value = true
	//console.log(row)
    form.value.name = row.name
   	form.value.place = row.place
}

双向绑定:

 <el-form label-width="50px">
      <el-form-item label="姓名">
        <el-input placeholder="请输入姓名" v-model="form.name"/>
      </el-form-item>
      <el-form-item label="籍贯">
        <el-input placeholder="请输入籍贯" v-model="form.place"/>
      </el-form-item>
    </el-form>

更新数据,先调接口,关闭弹窗,通知父组件更新列表

<el-button type="primary" @click="onUpdate">确认</el-button>
import axios from 'axios';
const onUpdate = async ()=>{
	await axios.patch(`/edit/${id}`, {
  	name: form.value.name, 
  	place: form.value.place,
 })
}

要传入id,我们补一个id 上面的 ${id} => ${form.value.id},姓名和籍贯都改改,async,await也写上。

const form = ref({
	name:'',
	place:'',
	id:''
})
const open = (row)=>{
	dialogVisible.value = true
	//console.log(row)
    form.value.name = row.name
   	form.value.place = row.place
   	form.value.id = row.id
}

关闭弹窗

dialogVisible.value = false

通知父组件做列表更新,是子传父,我们使用自定义事件。

<!--绑定事件,将 获取列表数据 的函数传过去-->
<Edit ref="editRef" @on-update="getList"/>
const emit = defineEmits(['on-update'])

emit('on-update')

这样就完成了

项目相关全部代码:

<!-- App.vue -->
<script setup>
import Edit from './components/Edit.vue'
import { onMounted, ref } from 'vue';
import axios from 'axios'

// TODO: 列表渲染
const list = ref([])
const getList = async () => {
  const res = await axios.get('/list')
  list.value = res.data  //赋值
}

onMounted(() => getList())
// TODO: 删除功能
const delList = async (id) => {
  await axios.delete(`/del/${id}`)
  getList()
}

// TODO: 编辑功能
//思路:打开弹框 - 回填数据 - 更新数据
const editRef = ref(null)

const onEdit = (row) => {
  editRef.value.open(row)
}
</script>

<template>
  <div class="app">
    <el-table :data=list>
      <el-table-column label="ID" prop="id"></el-table-column>
      <el-table-column label="姓名" prop="name" width="150"></el-table-column>
      <el-table-column label="籍贯" prop="place"></el-table-column>
      <el-table-column label="操作" width="150">
        <template #default="{ row }">
          <el-button type="primary" link @click="onEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="delList(row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <Edit ref="editRef" @on-update="getList" />
</template>

<style scoped>
.app {
  width: 980px;
  margin: 100px auto 0;
}
</style>

<!-- Edit.vue -->
<script setup>
// TODO: 编辑
import { ref } from 'vue'
import axios from 'axios';
// 弹框开关
const dialogVisible = ref(false)
const emit = defineEmits(['on-update'])
const form = ref({
  name: '',
  place: '',
  id: ''
})
const onUpdate = async () => {
  await axios.patch(`/edit/${form.value.id}`, {
    name: form.value.name,
    place: form.value.place,
  })
  dialogVisible.value = false  //关闭弹窗
  emit('on-update')
}
const open = (row) => {
  dialogVisible.value = true
  form.value.name = row.name
  form.value.place = row.place
  form.value.id = row.id
}
defineExpose({
  open
})
</script>

<template>
  <el-dialog v-model="dialogVisible" title="编辑" width="400px">
    <el-form label-width="50px">
      <el-form-item label="姓名">
        <el-input placeholder="请输入姓名" v-model="form.name" />
      </el-form-item>
      <el-form-item label="籍贯">
        <el-input placeholder="请输入籍贯" v-model="form.place" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="onUpdate">确认</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.el-input {
  width: 290px;
}
</style>

Day01小结

第一天,讲的是vue3的一些基础知识,做了一个小练习
love and peace
没学vue2的慎入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/640048.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第110题平衡二叉树

题目&#xff1a; 题解&#xff1a; class Solution { public:int height(TreeNode* root) {if (root NULL) {return 0;}int leftHeight height(root->left);int rightHeight height(root->right);if (leftHeight -1 || rightHeight -1 || abs(leftHeight - rightH…

【蓝桥杯选拔赛真题76】python找出元素 第十四届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python找出元素 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python找出元素 第十四届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

一文了解 FileBeat:诞生背景、发展历程与定义

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是ELK 2、FileBeat在ELK中的角色 3、File…

数据结构顺序表实现通讯录

目录 1. 前言&#xff1a; 2.通讯录项目的创建 3. 通讯录的实现 3.1 通讯录的初始化 3.2 通讯录的销毁 3.3 通讯录添加数据 3.4 通讯录查找数据 3.5 通讯录展示数据 3.6 通讯录删除数据 3.7 通讯录修改数据 4. 通讯录完整代码 4.1 test.c 4.2 SeqList.h 4.3 SeqLis…

OneAPI接入本地大模型+FastGPT调用本地大模型

将Ollama下载的本地大模型配置到OneAPI中&#xff0c;并通过FastGPT调用本地大模型完成对话。 OneAPI配置 新建令牌 新建渠道 FastGPT配置 配置docker-compose 配置令牌和OneAPI部署地址 配置config.json 配置调用的渠道名称和大模型名称 {"systemEnv": {&qu…

【虚拟机软件】 VMware Workstation Pro 17 新建 Linux 虚拟机教程(CentOS 7 版本)

文章目录 下载安装 VMware Workstation Pro 17 软件下载 Linux 的 ISO 映像文件Linux版本选择 新建虚拟机准备配置新建安装 后续设置文章导航 我是一名立志把细节说清楚的博主&#xff0c;欢迎【关注】&#x1f389; ~ 原创不易&#xff0c; 如果有帮助 &#xff0c;记得【点赞…

【全开源】填表统计预约打卡表单系统FastAdmin+ThinkPHP+UniApp

简化流程&#xff0c;提升效率 一、引言&#xff1a;传统表单处理的局限性 在日常工作和生活中&#xff0c;我们经常会遇到需要填写表单、统计数据和预约打卡等场景。然而&#xff0c;传统的处理方式往往效率低下、易出错&#xff0c;且不利于数据的统计和分析。为了解决这些…

报名倒计时两周|2024 OpenTiny 开源之夏项目直播解读回顾

5月16日&#xff0c;OpenTiny 开源社区成功举办了以《OpenTiny 开源之夏项目解读直播》为主题的直播活动。此次直播中&#xff0c;华为云的高级前端工程师曾令卡、华为云的高级前端工程师伍其和与10位开源之夏技术专家携手组成项目导师团&#xff0c;面向广大开发者一同深入探讨…

如何在go语言中调用c语言代码

1.安装c语言编译器 要使用cgo&#xff0c;需要安装c语言编译器 gcc 2.检查CGO_ENABLED时候开启 使用以下命令查看&#xff1a; go env CGO_ENABLED 如果go env CGO_ENABLED被禁用(为0),需要将其设置为开启(为1) 3.编写c语言程序&#xff0c;并用go语言调用c语言程序 1&#xff…

Design to code(2)

【碎碎念】从七点到十一点&#xff0c;累计用时4个小时完成的代码翻译Σ(&#xffe3;。&#xffe3;ノ)ノ DCDS图 顺序图&#xff08;支付过程&#xff09; 交互图&#xff08;订单&#xff09; 我的代码 Payment public class Payment { //定义支付订单金额 private…

k8s集群部署成功后某个节点突然出现notready状态解决办法

通过&#xff1a; kubectl get nodes 查看master1节点为not ready 通过查看日志&#xff1a; journalctl -f -u kubelet.service 看到这里 查看状态&#xff1a; systemctl status kubelet.service 重启一样会报错 执行&#xff1a; swapoff -a 执行后&#xff0c;重启…

以及Spring中为什么会出现IOC容器?@Autowired和@Resource注解?

以及Spring中为什么会出现IOC容器&#xff1f;Autowired和Resource注解&#xff1f; IOC容器发展史 没有IOC容器之前 首先说一下在Spring之前&#xff0c;我们的程序里面是没有IOC容器的&#xff0c;这个时候我们如果想要得到一个事先已经定义的对象该怎么得到呢&#xff1f;…

HCIP-Datacom-ARST自选题库__ISIS判断【23道题】

1.IS-1S快速收敛是为了提高路由的收敛速度而做的扩展特性&#xff0c;包含PRC和I-SPF&#xff0c;其中PRC只对发生变化的路由进行重新计算&#xff0c;而I-SPF只对受影响的节点进行路由计算。√ 2.在I5-S协议视图下配置ipv6 preference&#xff0c;该命令的作用是配置|5-IS协议…

『哈哥赠书 - 53期』-『深入浅出 Spring Boot 3.x』

⭐️ 《深入浅出 Spring Boot 3.x》 ⭐️ 学习Spring Boot的必读之书 在 Java 后端开发领域&#xff0c;功能强大的 Spring 开源框架不仅是首选&#xff0c;也是事实上的标准。但由于 Spring 存在配置烦琐、部署不易、依赖管理困难等问题&#xff0c;因此基于 Spring 的快速开…

【IDEA软件应用篇】IDEA基础开发设置和开发快捷键

IDEA是一种集成开发环境&#xff0c;可以运行java代码。 本篇文章你将收获到下面的知识&#xff1a; &#xff08;1&#xff09;IDEA如何设置字体大小快捷键 &#xff08;2&#xff09;如何解决每次进IDEA时&#xff0c;进去的页面都是上次使用完时的那个页面 &#xff08;3&am…

【学习笔记】Windows GDI绘图(四)矩阵Matrix详解

矩阵Matrix 基于矩阵在GDI绘图的重要性&#xff0c;所以想深入了学习矩阵的相关属性与方法。 先上个本文中所有的函数图例演示吧。 原型&#xff1a; namespace System.Drawing.Drawing2D;public sealed unsafe class Matrix : MarshalByRefObject, IDisposableMatrix类封装…

(Java企业 / 公司项目)配置Linux网络-导入虚拟机

公司给了我一个IP地址 &#xff0c;提供了一个虚拟机或者自己搭建虚拟机&#xff0c;还有提供登录的账号密码 可以查看我之前的文章 VMware Workstation Pro 17虚拟机超级详细搭建&#xff08;含redis&#xff0c;nacos&#xff0c;docker, rabbitmq&#xff0c;sentinel&…

民国漫画杂志《时代漫画》第16期.PDF

时代漫画16.PDF: https://url03.ctfile.com/f/1779803-1248612470-6a05f0?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

EMQX 的初始IP改为自己的实际IP

分类 EMQX Dashboard&#xff08;控制台&#xff09;: Dashboard提供了一个Web界面&#xff0c;用于管理和监控EMQX的运行状态。您可以通过配置dashboard.listeners.http.bind来设置Dashboard的监听地址和端口。例如&#xff0c;如果您想要Dashboard在所有网络接口上监听&#…

【oracle004】oracle内置函数手册总结(已更新)

1.熟悉、梳理、总结下oracle相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 总结源文件资源下载地址&#x…