持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情。
今天主要是学习toRef的特点与作用,customRef在实战中的应用。
toRef函数的特点与作用
toRef为响应式对象上的某个属性创建一个ref引用,更新时引用对象会同步更新;
示例:
<template>
<div>
<div>{{ state.total }}</div>
<button @click="update">更新数据</button>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "Home",
setup() {
let state = reactive({
total: 10,
});
let update = () => {
let total = state.total;
total++;
};
return {
state,
update,
};
},
});
</script>
这么直接赋值给变量total,对total进行值得更新,视图是不会更新的;
引入toRef,使用toRef进行引用,改变total的值,视图就会更新了:
let update = () => {
// let total = state.total;
let total = toRef(state, "total");
total.value++;
};
还有一种情况也是不会更新视图的:
let update = () => {
// let total = state.total;
// let total = toRef(state, "total");
let total = toRef({ total: 10 }, "total");
total.value++;
};
注意:如果通过toRef创建的数据修改时,并不会触发视图界面的更新,因为toRef的本质是引用,与原始数据有关联。
customRef在实战中的应用
customRef用于自定义一个ref,可以显式地控制依赖追踪和触发反应,接受一个工厂函数,两个参数分别是用于追踪的track与用于触发响应的trigger,并返回一个带有get和set属性的对象,在实际开发中可以实现防抖函数。
示例:给一个input框做个防抖处理:
使用customRef封装一个防抖函数:
import { customRef } from "vue";
export function useDebounced<T>(value: T, delay = 300, callback: Function) {
let timer: any = null;
return customRef((track, trigger) => {
return {
get() {
track(); // 告诉vue追踪数据
return value; // 这里返回的就是input传入的值
},
set(newVal: T) {
// 使用clearTimeout和setTimeout实现防抖
clearTimeout(timer);
timer = setTimeout(() => {
value = newVal;
callback(value);
trigger(); // 告诉vue去更新页面
}, delay);
},
};
});
}
然后在页面中引用,对input框的输入做一个防抖处理:
<template>
<div>
<div>
<input type="text" v-model="keywords" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useDebounced } from "@/hook/debounced";
export default defineComponent({
name: "Home",
setup() {
let keywords = useDebounced<string>("", 500, (val: string) => {
console.log("输入的值", val);
});
return {
keywords,
};
},
});
</script>
接下来继续学习Vue3的知识点~