---
typora-copy-images-to: media
---
# vue3的补充知识
## 组合式API
### 针对数据定义
ref:可以定义任意类型的响应式数据,在js中取值、赋值,需要用`数据.value`,在模板中,直接使用就行;如果修饰引用类型数据,value值是一个Proxy对象。
reactive:只能修饰引用类型数据,是一个Proxy对象。
shallowRef:ref对数据的监听是深层次监听,shallowRef是浅层次的监听;ref监听数据是将原数据进行拷贝,监听的是拷贝的数据,shallowRef只监听原数据。
toRaw:将响应式数据转成原数据。
createApp:创建vue实例的api。
toRef:将一个非响应式数据修饰成响应式的数据。
toRefs:将一个reactive对象中的每个属性都转成ref响应式数据,此时模板中使用这个属性值的时候,需要`.value`。
shallowReactive:是一个浅层次监听的Proxy对象。
readOnly:让一个数据变成只读数据。
shallowReadOnly:让浅层次的数据变成只读的,深层次还可以修改。
### 检测对象的方法
isRef:判断一个数据是否是一个ref对象
isReactive:判断一个对象是否有reactive创建的响应式对象
isReadonly:判断一个对象是否有readonly创建的只读数据
isProxy:检查一个对象是否是由reactive或readonly方法创建的响应式数据
### 比较常用的API
watch:监听器,监听某个数据发生变化,就执行一段逻辑
watchEffect:立即执行的监听器,第一次就会执行;这个函数中用到的数据变化就会执行,不用指定监听某个数据。
computed:计算属性,得到一个依赖其他数据变化重新计算得到新数据的方法。
nextTick:数据更新后,vue内容会更新视图,更新视图的操作是异步的。如果要获取到更新后的视图或dom节点,就使用nextTick。(nextTick的回调函数在调用的时候,是在一个异步的回调函数中执行的,这个异步任务是宏任务还是微任务?首先为了性能先用了微任务,如果微任务出错了会调用宏任务)
### 跟数据传递相关的
defineProps:用于接收父通过属性给子传递的数据
defineEmits:用于接收父给子绑定的事件
defineExpose:用于将自己的数据或方法暴露出去
getCurrentInstance:用于获取当前组件实例对象
### 生命周期钩子函数
在vue3的setup语法糖中,直接就是创建后的阶段,所以在组合式API中是没有创建前后的钩子函数。
onBeforeMount:挂载前
onMounted:挂载后
onBeforeUpdate:更新前
onUpdated:更新后
onBeforeUnmount:销毁前
onUnmounted:销毁后
## 事件循环
js是一门单线程语言,也就意味着js同一时间只能做一件事,无法同时进行多个任务,也就造成了运行的性能比较低。
为了提高性能,js内置了异步的任务,希望同一时间,能进行多个任务。
异步任务跟单线程是有冲突、矛盾,js利用好基友浏览器去处理了异步任务。
js执行js代码的时候,首先会直接在自己的线程中执行同步代码,碰到异步代码的时候,会交给浏览器的`webapi`去**处理**,浏览器的处理只是在等待这段代码要执行的时机,当等到这段代码执行的时机后,会将需要执行的代码放在一个**队列**中。js线程将所有同步任务执行结束后,会从队列中依次将代码放在js线程中去执行。
异步任务分两种,所以队列分两种:
宏任务会放在宏队列中,微任务会放在微队列中。
宏任务:每隔一段时间执行的定时器 + 延迟执行的定时器 + 原生ajax
微任务:Promise的then和catch + await
js线程将所有同步代码执行结束后,会先清空微队列,然后再去清空宏队列,然后再清空微队列,然后再清空宏队列。。。。
将整个script代码当做是一个宏任务,先清空宏队列,再清空微队列,。。。
## 组件通信
1. **父传子**
父组件中在子组件标签上添加属性,就是给子组件传递数据
子组件中通过defineProps接收数据
2. **子传父**
父组件中在子组件标签上绑定事件(自定义事件名称),事件函数在父组件中定义的
子组件中通过defineEmits接收事件
子触发事件,并传递实参
父组件的事件函数中可以通过形参接收数据
3. **ref**
直接获取子组件实例就能获取到子组件的数据和方法了
父组件中定义ref数据,值为空
在父组件中给子组件标签添加ref属性,值是定义好的ref数据
子组件中将父组件需要的方法和数据通过defineExpose暴露出去
父组件通过`ref数据.value`获取到子组件实例对象,其中就有数据和方法
父给子传递数据:
在父组件中给子组件标签添加ref属性,值是定义好的ref数据
子组件中将父组件需要的函数通过defineExpose暴露出去
父组件通过`ref数据.value`获取到子组件实例对象,其中就有暴露出来的函数
函数调用,传递实参
在子组件中定义函数的地方可以使用形参接收
4. 祖孙组件数据传递
provide传递和inject接收。
provide在祖组件中提供数据 ==> 传递
inject在孙组件中接收数据 ==> 接收
祖向孙传递数据:
祖用provide(键, 值)传递
孙用inject(键)可以返回一个值
孙向祖传递数据:
祖用provide传递一个函数
孙用inject接收函数,调用函数传递实参
祖定义的函数中,使用形参进行接收
5. **插槽**
插槽通常传递的不是数据,是页面结构。
默认插槽:
具名插槽:
作用域插槽:
6. vuex和pinia
7. 透传(给子组件标签添加属性,如果子组件没有使用props接收,就会将这个属性放在子组件最大的标签上,例如给子组件标签添加style、class)
8. 全局数据
在main.ts中,给`app.config.globalProperties.属性名`赋值,这个属性名就是全局的数据名称,我们可以在任意组件中使用。
9. **利用第三方插件 mitt**
下载安装:
```shell
npm i mitt
```
单独封装一个文件:
```ts
import mitt from 'mitt'
const bus = mitt()
export default bus
```
在组件中可以绑定事件,可以触发事件:
```ts
bus.on(事件名称, 函数) // 绑定事件
bus.emit(事件名称, 参数) // 触发事件并传递数据
```