Vue3 其它Composition API
一、shallowReactive与shallowRef
1.shallowReactive:只是处理对象最外层属性的响应式(浅响应式)
2.shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。
3.什么时候使用?
(1).如果有一个对象数据,结构比较深,但变化只是外层属性变化===>shallowReactive。
(2).如果有一个对象数据,后续功能不会修改该对象中的属性,而是生成新的对象来替换===>shallowRef
<template><h1>信息</h1><h1>{{ person }}</h1><h1>姓名:{{ name }}</h1><h1>年龄:{{ age }}</h1><h1>薪资:{{ salary }}k</h1><button @click="updateName">点击修改</button> <button @click="age++">点击长大</button> <button @click="salary++">涨薪</button> <hr><h1>{{ sum.y }}</h1><button @click="sum.y++">点击+1</button>
</template><script>
import { reactive,toRef, shallowReactive,shallowRef } from 'vue'
export default {name: 'App',setup() {// let person = shallowReactive({//只考虑浅层(第一层)数据的响应式let person = reactive({name:'张三',age:18,job:{salary:20}})let sum =shallowRef({y:0 //此处无法操作y的值实现响应式})function updateName(){person.name='李四'}return {person,name:toRef(person,'name'),age:toRef(person,'age'),salary:toRef(person.job,'salary'),updateName,sum}}
}
</script>
二、readonly与shallowReadonly
1.readonly:让一个响应式数据变为只读的(深只读)。
2.shallowReadonly:让一个响应式数据变为只读的(浅只读)。
3.应用场景:不希望是数据被修改时。
let person = reactive({
name:'张三',
age:18,
job:{
salary:20
}
})
person = readonly(person) // 全部数据都不允许修改
person = shallowReadonly(person) // 可以修改深层数据,如person.job.salary
三、toRaw与markRaw
1.toRaw:
(1).作用:将一个由 reactive 生成的响应式对象转为普通对象。
(2).使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作都不会引起页面更新。
2.markRaw:
(1).作用:标记一个对象,使其永远不会再成为响应式对象。
(2).应用场景:
(1.有些许hi不应被设置为响应式的,例如复杂的第三方类库等。
(2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能,如在数据源中引入了axios等大数据包。
<template><h1>信息</h1><h1>姓名:{{ name }}</h1><h1>年龄:{{ age }}</h1><h1>薪资:{{ job.salary }}k</h1><h1 v-show="person.car">汽车信息:{{ person.car }}</h1><button @click="updateName">点击修改</button> <button @click="age++">点击长大</button> <button @click="job.salary++">涨薪</button> <button @click="showRawPerson">点击输出原始person</button> <button @click="addCar">点击添加车辆信息</button> <button @click="addCarPrice" v-show="person.car">点击价格+1</button> <hr /><h1>{{ sum }}</h1><button @click="sum++">点击+1</button>
</template><script>
import { reactive, toRefs, ref, toRaw, markRaw } from "vue";
export default {name: "App",setup() {let sum = ref(0);let person = reactive({name: "张三",age: 18,job: {salary: 20,},});function updateName() {person.name = "李四";}function showRawPerson() {// console.log(person) // 输出由reactive构建的proxy对象console.log(toRaw(person)); //输出person原生对象}function addCar(){let car ={ name:'奔驰',price:20 }person.car = markRaw(car)console.log(person.car)}function addCarPrice(){person.car.price++console.log(person.car.price)}return {person,...toRefs(person),updateName,sum,showRawPerson,addCar,addCarPrice};},
};
</script>
四、customRef
1.作用:创建一个自定义的ref,并对其依赖项跟踪(track)和更新触发(trigger)进行显示控制。
2.实现防抖效果:
<template><span>请输入一段文字:</span><input type="text" v-model="text"><br><span>{{ text }}</span>
</template><script>
import { ref, customRef } from "vue";
export default {name: "App",setup() {//使用Vue准备好的内置ref// let text =ref('')let text = myRef('',500)//防抖function myRef(value,dalay){let timerreturn customRef((track,trigger)=>{return {get(){track()return value},set(newValue){clearTimeout(timer)timer = setTimeout(() => {trigger()value = newValue}, dalay);}}})}return {text};},
};
</script>
五、provide与inject
1.作用:实现祖先与后代组件间的通信。
2.套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据。
3.具体写法:
(1).祖先组件中:
import { provide } from 'vue'
setup(){
......
let car = reactive({name:'奔驰',price:'40万'})
provide('car',car)
......
}
(2).后代组件中:
import { inject } from 'vue'
setup(){
......
const car = inject('car')
return {car}
......
}
六、响应式数据的判断
isRef: 检查一个值是否为一个 ref 对象
isReactive: 检查一个对象是否是由
reactive
创建的响应式代理isReadonly: 检查一个对象是否是由
readonly
创建的只读代理isProxy: 检查一个对象是否是由
reactive
或者readonly
方法创建的代理
<template><div class="app">我是App组件</div>
</template><script>
import { isProxy,isReactive,isReadonly,isRef, reactive, readonly,ref } from "vue";
export default {name: "App",setup() {let car = ref({ name: "奔驰", price: 20 });let sum =ref(0)let car1 = readonly(car)console.log(isRef(sum))// ref构建的对象,其value所存值是由reactive构建,所以value是reactiveconsole.log(isReactive(car.value))//输出为trueconsole.log(isProxy(car.value))//输出为true// 通过readonly包装后的car1的value值也等同于reactiveconsole.log(isReadonly(car1))return { car,sum,car1 };},
};
</script><style>
* {padding: 10px;
}
.app {background-color: orange;
}
</style>