customRef
定义
创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。
customRef()预期接收一个工厂函数作为参数,这个工厂函数接受track和trigger两个函数作为参数,并返回一个带有get和set方法的对象。 一般来说,track()应该在get()方法中调用,而trigger()应该在set()中调用。然而事实上,你对何时调用、是否应该调用他们有完全的控制权。
使用场景之过滤敏感词
创建一个500ms的防抖ref,input输入时侦听有无敏感词并给提示、清空input,代码如下:
const shitWords = ['nmsl', 'dsb', 'zz', 'mlgb'];
const myCustomRef = (value) => {
return customRef((track, trigger) => {
let timer;
return {
// 读取数据
get() {
console.log("myCustomRef这个容器中的数据被读取了:", value);
// debugger
track(); // 通知vue 追踪value的变化
return value;
},
// 变更数据
set(newValue){
console.log("myCustomRef这个容器中的数据被修改了:", newValue);
if (shitWords.includes(newValue as string)){
alert('讲文明,树新风!')
value = '';
} else {
value = newValue; // value是一个形参,也是函数作用域里面的一个变量
}
clearTimeout(timer);
timer = setTimeout(() => {
trigger(); // 通知vue 去重新解析模板
}, 500);
}
}
})
}
const keyCode = myCustomRef("hello");
shallowRef
定义
ref()的浅层作用形式。和ref()不同,浅层ref的内部值将会原样存储和暴漏,并且不会被深层递归地转为响应式。只有对.value的访问是响应式的。
使用场景
shallowRef()常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。
triggerRef
定义
强制触发依赖于一个浅层ref的副作用,这通常在对浅引用的内部值进行深度变更后使用。
使用场景
常与shallowRef搭配使用,如下:
const shallCount = shallowRef({
count: 1
})
const change = () => {
// 会变,但是没有实时反映到视图上,通过下面的trigger可触发
shallCount.value.count++;
// 强制触发依赖于一个浅层ref的副作用,这通常在对浅应用的内部值进行深度变更后使用
triggerRef(shallCount);
}
const change1 = () => {
shallCount.value.count++;
}
PS:请注意,浅层ref如果修改其value值的某些属性,值会变化但不会响应式地变化(即不会反应到视图内),这个效果和基于原始对象的toRef是一致的。