目录
1、shallowRef与shallowReactive保护数据
2、readonly与shallowReadonly保护数据
1、shallowRef与shallowReactive保护数据
1.1、shallowRef
1)作用:创建一个响应式数据,但只对顶层属性进行响应式处理。
2)用法:
let myVar = shallowRef(initialValue);
3)特点:只能跟踪引用值的变化,不关心值内部的属性变化
1.2、shallowReactive
1)作用:创建一个浅层响应式对象,只会使对象的顶层属性变成响应式的,对象内部的嵌套属性则不会变成响应式的
2)用法:
const myObj = shallowReative({...})
3)特点:对象的顶层属性是响应式的,但嵌套对象的属性不是。
1.3、总结
通过使用shallowRef()和shallowReactive()来绕开深度响应。浅层式API创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问变得更快,可提升性能。
2、readonly与shallowReadonly保护数据
2.1、readonly
1)作用:用于创建一个对象的深只读副本。
2)用法:
const original = reactive({....})
const readOnlyCopy = readonly(original)
3)特点:
- 对象的所有嵌套属性都将变为只读
- 任何尝试修改这个对象的操作都会被阻止(在开发模式下,还会在控制台中发出警告)
4)应用场景:
- 创建不可变的状态快照。
- 保护全局状态或配置不被修改
2.2、shallowReadonly
只处理浅层次的只读
1)作用:与readonly类似,但是只作用于对象的顶层属性。
2)用法:
const original = reactive({....})
const shallowReadOnlyCopy = shallowReadonly(original);
3)特点:
只将对象的顶层属性设置为只读,对象内部的嵌套属性仍然是可变的。
3、ToRaw与markRaw
3.1、toRaw
1)作用:用于获取一个响应式对象的原始对象,toRaw返回的对象不再是响应式的,不会触发视图更新。
官网描述:这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法,不建议保存对原始对象的持久引用,请谨慎使用。
何时使用?在需要将响应式对象传递给非Vue的库或外部系统时,使用toRaw可以确保他们收到的是普通对象
3.2、markRaw
1) 作用:标记一个对象,使其永远不会变成响应式的。
例如使用mockjs时,为了防止误把mockjs变成响应式对象,可以使用markRaw去标记mockjs
4、customRef
1)作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行逻辑控制。
2)具体代码实现:
<template>
<div class="app">
<h2>{
{ msg }}</h2>
<input type="text" v-model="msg" />
</div>
</template>
<script setup lang="ts" name="App">
import {ref,customRef} from 'vue'
//使用Vue提供的customRef定义响应式数据
let initValue = '你好'
let timer:number;
// track(跟踪)、trigger(触发)
let msg = customRef((track,trigger)=>{
return {
// msg被读取时调用
get(){
track() //告诉vue数据msg很重要,你要对msg进行持续关注,一旦msg变化就去更新
return initValue
},
// msg被修改时调用
set(value){
clearTimeout(timer)
setTimeout(()=>{
console.log('set',value)
initValue = value
trigger() //通知vue一下数据msg变化了
},1000)
}
}
})
</script>
4.1、改进hooks
《useMsgRef.ts》
import {customRef} from 'vue'
export default function(initValue:string,delay:number){
//使用Vue提供的customRef定义响应式数据
let timer:number;
// track(跟踪)、trigger(触发)
let msg = customRef((track,trigger)=>{
return {
// msg被读取时调用
get(){
track() //告诉vue数据msg很重要,你要对msg进行持续关注,一旦msg变化就去更新
return initValue
},
// msg被修改时调用
set(value){
clearTimeout(timer)
setTimeout(()=>{
console.log('set',value)
initValue = value
trigger() //通知vue一下数据msg变化了
},delay)
}
}
})
return {msg}
}
<template>
<div class="app">
<h2>{
{ msg }}</h2>
<input type="text" v-model="msg" />
</div>
</template>
<script setup lang="ts" name="App">
import useMsgRef from './useMsgRef'
// 使用useRef来定义一个响应式数据且有延迟效果
let {msg} = useMsgRef('你好',2000)
</script>