一、认识Composition API
1. Options API弊端
- 当我们实现某一个功能时,这个功能对应的代码逻辑会被拆分到各个属性中
- 当我们组件变得更大、更复杂时,逻辑关注点的列表就会增长,那么同一个功能的逻辑就会被拆分的很分散
2. 认识Composition API
- 可以将同一个逻辑关注点相同的代码收集在一起
- setup可以代替之前编写的大部分其他选项
vue单项数据流规范:父组件将数据传递给子组件后,子组件拿到数据之后,只能用,不能修改;子组件可以将事件传递给父组件,父组件对该事件进行监听,改变父组件中的数据。
二、setup的使用
1. setup函数的基本使用
- setup函数的参数
- props
- 父组件传递过来的属性会被放到props对象中
- context
- attrs:所有的非prop的attribute
- slots:父组件传递过来的插槽
- emit:当组件内部需要发出事件时会用到emit
- props
- setup函数的返回值
- setup的返回值可以在模板template中被使用
2. setup中数据的响应式
- Ref API
- ref的使用
- ref会返回一个可变的响应式对象,该对象作为一个响应式的引用维护着它内部的值
- 它内部的值是在ref的value属性中被维护的
- 在模板中引入ref的值,Vue会自动帮助我们进行解包,所以在模板中不需要通过ref.value的方式来使用
- 但是在setup函数内部,它依然是一个ref引用,所以对其进行操作时,我们依然需要使用ref.value的方式
- ref的API
- unref:获取ref引用中的value
- isRef:判断值是否是一个ref
- shallowRef:创建一个浅层的ref对象
- triggerRef:手动触发和shallowRef相关联的副作用
- ref的使用
- Reactive API
- 如果想为在setup中定义的数据提供响应式的特性,那么我们可以使用reactive函数
const info = reactive({ name: "Messi", age: 35 })- 为什么会变成响应式
- 因为当我们使用reactive函数处理我们的数据之后,数据再次被使用时就会进行依赖收集
- 当数据发生改变时,所有收集到的依赖都是进行对应的响应式操作
- 事实上,我们编写的data选项,也是内部交给了reactive函数将其编成响应式对象的
- reactive判断的API
- isProxy:检查对象是否由reactive或readonly创建的proxy
- isReactive:检查对象是否由reactive创建的响应式代理;如果该代理是readonly建的,但是包裹了由reactive创建的另一个代理,它也会返回true
- isReadonly:检查好对象是否由readonly创建的只读代理
- toRaw:创建reactive或readonly代理的原始对象
- shalloReactive:创建一个响应式代理,它跟踪其自身property的响应性,但不执行嵌套对象的深层响应式转换
- shallowReadonly:创建一个proxy,使其自身的property为只读,但不执行嵌套对象的深度只读转换
- toRefs
- 对reactive返回的对象进行解构获取值,解构出来的变量不再是响应式的
- toRefs可以将reactive返回的对象中的属性都转成ref
const info = reactive({ name: "Messi", age: 35 }) const { name, age } = toRefs(info) - toRef
- 只希望转换一个reactive对象中的属性
cons name = toRef(info, "name")
- Reactive和Ref的区别
- 传入的类型
- reactive要求必须传入一个对象或者数组类型
- ref可以传入基本数据类型,也可以传入复杂数据类型
- 应用场景
- reactive应用于本地的数据;多个数据之间是有关系的
- 其他的场景基本都用ref
- 传入的类型
- readonly
- 认识readonly
- readonly会返回原始对象的只读代理
- readonly的入参
- 普通对象
- reactive返回的对象
- ref的对象
- readonly的使用
- readonly返回的对象是不允许修改的
- 经过readonly处理的原来的对象是允许被修改的
- 其本质就是readonly的对象的setter方法被劫持了
setup中禁用this
- 认识readonly
三、computed函数的使用
1. 使用方式一
- 接受一个getter函数,并为getter函数返回的值,返回一个不变的ref对象
const fullName = computed(() => {
return firstName.value + " " + lastName.value
})
2. 使用方式二
- 接收一个具有get和set的对象,返回一个可变的ref对象
const fullName = computed({
get: () => {
return firstName.value + " " + lastName.value
},
set: newValue => {
const names = newValue.split(" ")
firstName.value = names[0]
lastName.value = names[1]
}
})
四、组件的生命周期函数
因为setup是围绕beforeCreate和created生命周期钩子运行的,所以不需要显示的定义他们
五、Provide/Inject使用
1. Provide函数
- 可以通过Provide来定义每个Property
- provide可以传入两个参数
- name:提供属性名称
- value:提供属性值
let info = { name: "why", age: 18 } provide("info", info)
2. Inject函数
- 在后代组件中可以通过Inject来注入需要的属性和对应的值
- inject可以传入两个参数
- 要inject的property的name
- 默认值
const info = inject("info")
六、watch/watchEeffect
1. watch
- 需要手动执行侦听的数据源
const info = reactive({
name: "why",
age: 18,
friend: {
name: "kobe"
}
})
watch(info, (newValue, oldValue) => {
console.log(newValue, oldValue)
}, {
immediate: true,
deep: true
})
2. watchEffect
- 用于自动收集响应式数据的依赖
const age = ref(18)
const stopWatch = watchEffect(() => {
console.log(age.value)
})
if (age.value > 20) {
stopWatch()
}