ref是自动为其下数据添加响应式,而customRef就是手动为其下数据添加响应式,简单理解就是我们可以手动在vue3数据更新渲染的中间去做一些事情
利用customRef做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <template> <input type="text" v-model="keyword"> <h3>{{keyword}}</h3> </template> <script lang="ts" setup> import { customRef, ref } from 'vue'
function myref(value) { let timer return customerRef((track, trigger) => { return { get() { console.log(`从myref容器中读取数据,把初始化数据${value}给他`) // template中,h3里面的keyword是从get中读取的,当set已经将keyword的值修改了,但是h3里面的keyword一直不更新,是因为此处return的value是调用myref时传的初始化实参hello,所以页面不会更新 // 所以要先在get里面调用customRef的track方法去追踪。再在set里面设置修改 value = newValue,然后还要调用customRef里面的trigger方法去通知页面更新 track() return value }, set(newValue) { console.log(`将myref容器中的数据修改,修改成:${value}`) // 定时器是异步的,如果不清除定时器,会有bug,每次执行修改数据时,会卡顿,所以要清除定时器 clearTimeout(timer) timer = setTimeout(() => { value = newvalue trigger() // 通知vue去重新解析模板 }) } } }) } let keyword = myref('hello') // 使用自定义的ref </script> |
应用场景
防抖函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <template> <input v-model="text" > </template>
<script setup lang="ts"> import { customRef } from 'vue' function useDebouncedRef<T> (value: T, delay: number) { let timer: any = null return customRef<T>((track, trigger) => ({ get () { track() return value }, set (newValue) { clearTimeout(timer) timer = setTimeout(() => { value = newValue // ...do something trigger() }, delay) } })) }
const text = useDebouncedRef<string>('', 2000) </script> |
加强版的计算属性computed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <template> <el-slider v-model="value" @change="handleSlider" /> </template>
<script setup lang="ts"> import { customRef } from 'vue'
function useDebouncedRef<T> (value: T) { return customRef<T>((track, trigger) => ({ get () { track() return value }, set (newValue) { value = newValue trigger() } })) }
const value = useDebouncedRef<number>(0)
function handleSlider (e: number) { value.value = e } </script>
<style lang="scss" scoped> </style> |
更多
网上还有人通过这个做输入框v-model的双向数据绑定优化,在数据绑定过程中使用customRef进行数据做敏感词处理