一. toRefs/toRef
1. 背景
我们都知道reactive处理的对象是响应式的,但是使用ES6的解构语法对reactive对象进行处理,那么之后无论是修改解构后的变量name、age,还是修改reactive返回的原始对象info1,数据都不再是响应式的。
2. 使用
(1). toRefs
toRefs的函数,可以将reactive返回的对象中的属性都转成ref;如下代码,再次进行结构出来的 name 和 age 本身都是 ref的;
(2). toRef
只希望转换一个reactive对象中的属性为ref, 那么可以使用toRef的方法。
代码分享:
<template> <div> <h3>{{info1.name}}--{{info1.age}}</h3> <h3>{{name}}--{{age}}</h3> <h3>{{name2}}--{{age2}}</h3> <h3>{{age3}}</h3> <h3><button @click="EditAge">修改age</button></h3> </div> </template> <script> import { reactive, toRefs, toRef } from 'vue'; export default { setup(props, context) { // 1. reactive响应式对象 const info1 = reactive({ name: 'ypf', age: 18 }); const info2 = reactive({ name2: 'ypf', age2: 18 }); const info3 = reactive({ name3: 'ypf', age3: 18 }); // 2. 解构后则不再支持响应式 let { name, age } = info1; //3. 借助toRefs和toRef建立响应关系 (ref相关对象要通过.value拿值) let { name2, age2 } = toRefs(info2); let age3 = toRef(info3, "age3"); var EditAge = () => { info1.age++; age++; age2.value++; age3.value++; } return { info1, name, age, name2, age2, age3, EditAge } } } </script>
二. customerRef
1. 说明
创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制:
(1). 它需要一个工厂函数,该函数接受 track 和 trigger 函数作为参数;
(2). 并且应该返回一个带有 get 和 set 的对象;
2. 案例
实现:双向绑定的属性进行debounce(节流)的操作。
useDebounceRef.js
import { customRef } from 'vue';
// 自定义ref
export default function(value, delay = 300) {
let timer = null;
return customRef((track, trigger) => {
return {
get() {
track();
return value;
},
set(newValue) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger();
}, delay);
}
}
})
}
调用
<template> <div> <input v-model="msg" /> <h2>{{msg}}</h2> </div> </template> <script> import debounceRef from './hooks/useDebounceRef.js'; export default { setup() { const msg = debounceRef('hello msg'); return { msg } } } </script>