## Vue 3
### 1.环境搭建
**vue3项目创建**
> node版本要在15.0或更高版本
```shell
npm install vue@latest
```
这个指令将会安装并执行`create-vue`,它是Vue官方的项目脚手架工具。
> 创建时名称不要有大写
**开发环境**
`VScode` + `volar`插件
### 2.Vue API 风格
> vue的组件可以按两种不同的风格书写:**选项式API(vue2)** 和 **组合式API(vue3)**
> 大部分的核心概念在两种风格之间都是通用的。
**选项式API(Options API)**
使用选项式API,我们可以用包含多个选项的对象来描述组件的逻辑,例如`data`、`methods`、`created`、`mounted`、`computed`。选项所定义的属性都会暴露在函数内部的`this`上,它会指向当前的组件实例。
### 3.组合式API
#### 3.1 setup函数
- setup函数的执行时机:beforeCreate钩子之前 自动执行
- setup写代码的特点是:定义数据 + 函数 然后以对象方式return 后才可以在模板中使用
- `
```
- ref()函数:声明基础数据类型的值,
```html
```
#### 3.3 计算属性
`computed` 计算属性函数,基本思想和vue2的完全一致,组合式API下的计算属性只是修改了写法:
````html
````
注意:
1. 计算属性中不应该有“副作用”,比如异步请求或是修改dom
2. 计算属性应该是只读的,避免直接修改计算属性的值
#### 3.4 watch
作用:侦听*一个或者多个数据* 的变化,数据(响应式的数据)变化时执行回调函数,额外参数:
1. `immediate`:立即执行
2. `deep`:深度侦听
> deep 默认机制:通过watch监听的ref对象默认是千层监听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项
**精确监听**
````html
````
#### 3.5 生命周期函数
Vue3中生命周期API(选项式 VS 组合式)
| 选项式API | 组合式API |
| :------------------: | :-------------: |
| beforeCreate/created | setup |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeUnmount | onBeforeUnmount |
| unmounted | onUnmounted |
可多次执行函数
```html
```
#### 3.6 组件通信
**父传子**
基本操作:
1. 父组件中给子组件绑定属性
2. 子组件内部通过**props**选项接收
```html
```
```html
{{message}}
```
> 如果父组件传入的是响应式数据,则数据变化,子组件接受的数据也会变化
扩展:利用ts的泛型限定传参类型,**message参数为必传,arr为可选**。
```html
{{message}}
```
**子传父**
基本操作:
1. 父组件中给子组件标签通过`@`绑定事件
2. 子组件内部通过`$emit`方法触发事件
```html
```
```html
```
#### 3.7 模版引用
##### 3.7.1 获取模版实例
通过`ref标识`获取真实的dom对象或者**组件实例对象**。
示例:
```html
H1标签
```
**for循环**
```xml
```
```javascript
const cacheComDivRefInstance = ref([]);
const cacheComDivRef = (el)=>{
if(el){
cacheComDivRefInstance.value.push(el)
}
}
```
当组件在for循环内部时:
```xml
```
```javascript
let cacheComRefInstance = ref([]);
const cacheComRef = (el,index)=>{
if(el){
cacheComRefInstance.value[index] = el
}
};
```
##### 3.7.2 暴露实例的方法
`defineExpose()`
默认情况下在`
```
#### 3.8 provide和inject
作用和场景:**顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信**。
基本操作:
1. 顶层组件通过`provide`函数提供数据
```javascript
// 传递的过程中保持响应式,传入ref对象
provide('key',顶层组件中的数据)
```
2. 底层组件通过`inject`函数获取数据
```javascript
const message = inject('key')
```
**跨层传递方法**
场景:在底层组件需要修改顶层组件的数据,但单向数据流的原则,不建议直接修改传过来的数据。可以通过在顶层组件中提供一个修改数据的方法,传递给底层组件让其调用来修改数据。(谁的数据就由谁修改)
顶层组件:
```javascript
const setCount = ()=>{
count.value++
}
provide('setCount-key',setCount)
```
底层组件:
```javascript
const setCount = inject('setCount-key')
```
#### 3.9 获取组件实例
`getCurrentInstance` 的返回值是一个组件实例对象.
- 可以通过 `.ctx` 来访问该实例的上下文对象;
- 者通过 `.proxy `来访问该实例的代理对象。
两者的区别在于,通过` .ctx `访问的是真实的组件实例,而通过 `.proxy` 访问的是一个代理对象,该代理对象可以在模板中直接使用。
> getCurrentInstance 只能在 setup 或生命周期钩子中使用
```javascript
import { getCurrentInstance, onMounted} from 'vue'
export default {
setup() {
onMounted(() => {
const instance = getCurrentInstance()
console.log('实例', instance)
})
return {}
}
}
```
#### 3.10 nextTick
在 Vue 3 中 nextTick() 方法的行为和 Vue 2 中基本相似,但它进行了一些优化,以提高性能和稳定性。nextTick() 通过利用微任务(microtask)来确保在 DOM 更新之后执行回调,从而避免在同一事件循环中执行 DOM 操作。简单的理解是,当数据更新了,在dom中渲染后,自动执行函数。
```javascript
// 使用 nextTick() 方法
import { ref, nextTick } from 'vue';
const myValue = ref('initial value');
// 在 DOM 更新后执行回调
nextTick(() => {
console.log('DOM 已更新');
});
```
在onMounted中使用
```javascript
// 示例 2: 在 setup() 中使用 nextTick()
import { ref, onMounted, nextTick } from 'vue';
export default {
setup() {
const myValue = ref('initial value');
onMounted(() => {
// 在 DOM 更新后执行回调
nextTick(() => {
console.log('DOM 已更新');
});
});
return {
myValue,
};
},
};
```