# 常用 Composition API
# setup
setup 是 Vue3.0 中的一个新的配置项,值为一个函数
组件中所用到的:数据,方法等,均要配置在 setup 中
setup 函数的两种返回值 :
- 若返回一个对象,则对象中的属性,方法,在模板中可以直接使用
- 若返回一个渲染函数:则可以自定义渲染内容
** 注意 : **
- 尽量不要与 Vue2 配置混用
- Vue2 配置 (data, methods, computed…) 中可以访问但 setup 中的属性,方法
- 在 setup 中不能访问到 Vue2 配置 (data, methods, computed)
- 如果有重名,setup 有限
- setup 不能是一个 async 函数,因为返回值不再是 return 的对象,而是 promise, 模板看不到 return 对象中的属性
- setup 执行的时机
- 在 beforeCreate 之前执行一次,this 是
undefined
- 在 beforeCreate 之前执行一次,this 是
- setup 的参数
- props : 值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
- context : 上下文对象
- attrs : 值为对象,包含:组件外部传递过来,但是没有在 props 配置中声明的属性,相当于 this.$attrs
- slots : 收到的插槽内容,相当于 this.$slots
- emit: 分发自定义事件的函数,相当于 this.$emit
# ref
ref 用于定义一个响应式的数据
语法 : const xxx = ref(initValue)
- 创建一个包含响应式数据的引用对象 (reference 对象)
- JS 中操作数据: xxx.value
- 模板中读取数据:不需要.value, 直接:
<div>{{xxx}}</div>
备注 :
- 接收的数据可以是:基本类型,也可以是对象类型
- 基本类型的数据:响应式依然是靠
Object.defineProperty()的get与set完成的 - 对象类型的数据:内部使用了 Vue3 中的一个新函数 ——reactive 函数
# reactive 函数
定义一个对象类型的响应式数据 (基本类型不要用它,要用 ref 函数)
语法 : const 代理对象 = reactive(源对象) 接收一个对象 (或数组), 返回一个代理对象 (proxy 对象)
reactive 定义的响应式数据是深层次的
# Vue 中的响应式原理
# vue2 中的响应式
实现原理 :
对象类型:通过
Object.defineProperty()对属性的读取,修改进行拦截 (数据劫持)数组类型:通过重写更新数组的一系列方法来实现拦截. (对数组的变更方法进行了包裹)
1
2
3
4Object.defineProperty(data, 'count', {
get(){},
set(){}
})
存在问题
- 新增属性,删除属性,界面不会更新
- 直接通过下标修改数组,界面不会自动更新
# vue3 中的响应式
- 实现原理 :
- 通过 Proxy (代理) : 拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等
- 通过 Reflect (反射) : 对被代理对象的属性进行操作
# ref 对比 reactive
- 从定义数据角度对比 :
- ref 用来定义:基本数据类型
- reactive 用来定义:对象 (或数组) 数据类型
- 备注 : ref 也可以用来定义对象 (或数组) 类型数据,它内部会自动通过 reactive 转为代理对象
- 从原理角度对比 :
- ref 通过
Object.defineProperty()的 get 和 set 来实现响应式 (数据劫持) - reactive 通过使用 Proxy 来实现响应式 (数据劫持), 并通过 Reflect 操作源对象内部的数据
- ref 通过
- 从使用角度对比 :
- ref 定义的数据:操作数据需要
.value, 读取数据时模板直接读取不需要.value - reactive 定义的数据:操作数据与读取数据:军不需要
.value
- ref 定义的数据:操作数据需要
# computed 函数
与 vue2 中 computed 配置功能一致
写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import {computed} from 'vue'
setup() {
//简写形式, 未考虑计算属性的值被更改的情况
let fullName = computed(() => {
return person.firstName + '-' + person.lastName
})
//完整形式
let fullName = computed({
get() {
return person.firstName + '-' + person.lastName
},
set(value) {
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
}
