高级响应式系统 API
1、customRef
用于自定义一个 ref,可以显式地控制依赖追踪和触发响应,接受一个工厂函数,两个参数分别是用于追踪的 track 与用于触发响应的 trigger,并返回一个一个带有 get 和 set 属性的对象。
<template>
<div>
<p>refNum:{{refNum}}</p>
</div>
</template>
<script>
import {customRef} from 'vue'
export default {setup(){const cusRefs = (value)=>{return customRef((track,trigger)=>{
return {get(){track()
return value
},
set(newValue){
value = newValue;
trigger();}
}
})
}
const refNum = cusRefs(4)
setTimeout(()=>{refNum.value = 10;},3000)
return{refNum}
},
}
</script>
2、markRaw
显式标记一个对象为“永远不会转为响应式代理”,函数返回这个对象本身。
import {markRaw,reactive,isReactive} from 'vue'
export default {setup(){
let obj = markRaw({
name:'tom',
infos:{age:10}
})
console.log(isReactive(reactive(obj))) //false
// 尽管 `obj` 己经被标记为 markRaw 了, 但 markRaw.infos 并没有
console.log(isReactive(reactive(obj.infos))) //true
// 如果被 markRaw 标记了,即使在响应式对象中作属性,也依然不是响应式的
const objTemp = reactive({obj})
console.log(isReactive(objTemp.foo)) // false
console.log(isReactive(objTemp)) // true
return{}
},
}
3、shallowReactive
只为某个对象的私有(第一层)属性创建浅层的响应式代理,不会对“属性的属性”做深层次、递归地响应式代理,而只是保留原样。
<template>
<div>
<p>name:{{obj.name}}</p>
<p>age:{{obj.infos.age}}</p>
</div>
</template>
<script>
import {shallowReactive,isReactive} from 'vue'
export default {setup(){
let obj = shallowReactive({
name:'tom',
infos:{age:10}
});
// obj 中的属性是响应式的,可被传递
console.log(isReactive(obj)) ; //true
// 而 obj.infos 并不是响应式的
console.log(isReactive(obj.infos)); //false
setTimeout(()=>{
obj.name = "Json";
obj.infos.age++; // 数值变为 11 了,页面上也显示 11?console.log(obj)
},2000);
return {obj}
},
}
</script>
4、shallowReadonly
只为某个对象的自有(第一层)属性创建浅层的只读响应式代理,同样也不会做深层次、递归地代理,深层次的属性并不是只读的。
<template>
<div>
<p>name:{{obj.name}}</p>
<p>age:{{obj.infos.age}}</p>
</div>
</template>
<script>
import {shallowReadonly,isReadonly} from 'vue'
export default {setup(){
let obj = shallowReadonly({
name:'tom',
infos:{age:10}
});
// obj 中的属性是只读的,可被传递
console.log(isReadonly(obj)) ; //true
// 而 obj.infos 并不是只读的
console.log(isReadonly(obj.infos)); //false
setTimeout(()=>{
obj.name = "Json"; //Set operation on key "name" failed: target is readonly.
obj.infos.age++; // 数值变为 11 了, 但是页面显示原来的数据?console.log(obj)
},2000);
return {obj}
},
}
</script>
5、shallowRef
创建一个 ref 对象,将会追踪它的 .value 更改操作,但是并不会对变更后的 .value 做响应式代理转换(即变更不会调用 reactive)
import{ref,shallowRef,isReactive} from 'vue'
export default {setup(){let obj = shallowRef({});
let infos = ref({});
obj.value = {};
infos.value = {}
console.log(isReactive(obj)) ; //false
console.log(isReactive(infos)) ; //false
},
}
6、toRaw
返回由 reactive 或 readonly 方法转换成响应式代理的普通对象。这是一个还原方法,可用于临时读取,访问不会被代理 / 跟踪,写入时也不会触发更改。不建议一直持有原始对象的引用。请谨慎使用。
import{reactive,readonly,toRaw} from 'vue'
export default {setup(){let obj = {};
let resactives = reactive(obj);
let readonlys = readonly(obj);
// 还原 reactive/readonly 对象
console.log(toRaw(resactives) === obj) //true
console.log(toRaw(readonlys) === obj) //true
}
}
欢迎关注公众号(web 学习吧),一起学习进步: