文章目录
- 生命周期
- 自定义hook函数
- toRef
- 其他组合API
- shallowReactive与shallowRef
- readonly与shallowReadonlly
- toRaw 与 markRaw
- customRef
- provide与inject
- 响应式数据的判断
生命周期
除了直接写对应的钩子函数外,Vue3.0也提供了composition API形式的钩子函数,与Vue2.X对应的情况如下:
- beforeCreate===>setup
- created===>setup
- beforeMount ===>onBeforeMount
- mounted ===> onMounted
- beforeUpdate ===>onBeforeUpdate
- updated ===>onUpdated
- beforeUnmount===>onBeforeUnmount
- unmounted ===>onUnmounted
自定义hook函数
hook本质是一个函数,把setup函数中使用得composition API封装,能够更好的复用代码,让setup中的逻辑更加清楚易懂。
toRef
- 作用:创建一个ref对象,其value值指向另一个对象中的某个属性
- 语法:
const name = toRef(person,'name')
- 应用:要将响应式对象中的某个属性单独提供给外部使用
- 拓展:
toRefs
与toRef
功能一致
- ref:虽然通过ref也能实现我们想要的效果,可以省去繁琐的
person.
操作,直接通过Name,age等属性名来获取属性值并且可以进行修改,但是修改作用的对象不再是setup中定义的person对象中的属性,而是新生成的对象。
<template>
<h1>{{ person }}</h1>
<h1>姓名:{{ name }}</h1>
<h1>年龄:{{ age }}</h1>
<h1>工作:{{salary }}</h1>
<button @click="name = '李四'">姓名</button>
<button @click="age++">年龄</button>
<button @click="salary++">薪资</button>
</template>
<script>
import { reactive, ref } from 'vue';
export default {
setup(){
let person = reactive({
name:"张三",
age:24,
job:{
j1:{
salary:16
}}
})
return {
person,
name:ref(person.name),
age:ref(person.age),
salary:ref(person.job.j1.salary)
}
}
}
</script>
- toRef:能同时修改person以及return的数据
<template>
<h1>{{ person }}</h1>
<h1>姓名:{{ name }}</h1>
<h1>年龄:{{ age }}</h1>
<h1>工作:{{salary }}</h1>
<button @click="name = '李四'">姓名</button>
<button @click="age++">年龄</button>
<button @click="salary++">薪资</button>
</template>
<script>
import { reactive, toRef } from 'vue';
export default {
setup(){
let person = reactive({
name:"张三",
age:24,
job:{
j1:{
salary:16
}}
})
return {
person,
name:toRef(person,'name'),
age:toRef(person,'age'),
salary:toRef(person.job.j1,'salary')
}
}
}
</script>
- toRefs:可以操作多个属性,实现的效果与toRef一致
<template>
<h1>{{ person }}</h1>
<h1>姓名:{{ name }}</h1>
<h1>年龄:{{ age }}</h1>
<h1>工作:{{job.j1.salary }}</h1>
<button @click="name = '李四'">姓名</button>
<button @click="age++">年龄</button>
<button @click="job.j1.salary++">薪资</button>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
setup(){
let person = reactive({
name:"张三",
age:24,
job:{
j1:{
salary:16
}}
})
return {
person,
...toRefs(person)
}
}
}
</script>
其他组合API
shallowReactive与shallowRef
- shallowReactive只考虑对象第一层数据的响应式,深层次的不考虑
- ref在处理对象类型的响应式时会借助reactive,shallowRef不处理对象类型的响应式
- 使用场景:
- 如果有一个对象数据,结构比较深,但变化时只是外层属性变化===>shallowReactive
- 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生成新的对象来替换==>shallowRef
readonly与shallowReadonlly
- readonly:让一个响应式数据变为只读的(深只读)
- shallowReadonly:让一个响应式数据变为只读的(浅只读)
- 应用场景:不希望数据被修改时
toRaw 与 markRaw
- toRaw:
- 作用:将一个由reactive生成的响应式对象转为普通对象
- 使用场景:用于读取响应式对象的普通对象,对这个普通对象的所有操作,不会引起页面更新
- markRaw:
- 作用:标记一个对象,使其永远不会再成为响应式对象
- 应用场景:
- 有些值不应该被设置为响应式的,例如复杂的第三方类库等。
- 当渲染剧由不可变数据源的大列表时,跳过响应式转换可以提高性能。
customRef
- 作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制
<template>
<div>
<input type="text" v-model="keyword" />
<span>{{ keyword }}</span>
</div>
</template>
<script>
import { customRef } from "vue";
export default {
setup() {
function myRef(value) {
return customRef((track,trigger) => {
return {
get() {
console.log("get:", value);
track()//通知vue追踪value的变化
return value;
},
set(newValue){
console.log("set:",newValue)
value = newValue
trigger()//通知vue去重新解析模板
}
};
});
}
let keyword = myRef("Hello");
return {
keyword,
};
},
};
</script>
provide与inject
- 作用:实现祖孙组件间通信
- 套路:祖组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据
- 祖组件
setup() {
let car = reactive({
name: "车",
price: 24,
});
provide("car", car);
return {
...toRefs(car),
};
},
- 后代组件
setup(){
let car = inject('car')
return {
...toRefs(car)
}
}
响应式数据的判断
- isRef:检查一个值是否为一个ref对象
- isReactive:检查一个对象是否是由reactive创建的响应式代理
- isReadonly:检查一个对象是否是由readonly创建的只读代理
- isProxy:检查一个对象是否是由reactive或者readonly方法创建的代理