<script setup> import { debounceref } from './ref'; const text = debounceref('',1000) </script> <template> <div> <input v-model="text"> </div> <div>{{text}}</div> </template> <style scoped> </style>
我们想实现这样的效果:输入框中双向绑定了一个响应式数据text,当我们从输入框中改变text中的值时,我们想要text的值过一定的时间再做变更,类似一个防抖效果。
所以上面的关键就是实现debounceref()这个函数
debounceref(value,delay)
import { customref } from "vue"; export function debounceref(value,delay = 1000){ let timer; return customref((track,trigger) =>({ get(){ //依赖收集 track() return value }, set(val){ cleartimeout(timer) timer = settimeout(()=>{ //派发更新 trigger() value = val },delay) } })) }
函数接收两个参数:
第一个参数,绑定的值。
第二个参数,想要延迟多少秒更新
我们利用了vue内部提供的一个实现自定义ref的函数,该函数接收一个工厂函数,该函数必须返回一个对象,其中包含get和set函数
customref()源码
export function customref<t>(factory: customreffactory<t>): ref<t> { return new customrefimpl(factory) as any } export type customreffactory<t> = ( track: () => void, trigger: () => void, ) => { get: () => t set: (value: t) => void }
customrefimpl源码
class customrefimpl<t> { public dep?: dep = undefined private readonly _get: returntype<customreffactory<t>>['get'] private readonly _set: returntype<customreffactory<t>>['set'] public readonly __v_isref = true constructor(factory: customreffactory<t>) { const { get, set } = factory( () => trackrefvalue(this), () => triggerrefvalue(this), ) this._get = get this._set = set } get value() { return this._get() } set value(newval) { this._set(newval) } }
customrefimpl类中主要做了两件事,依赖收集trackrefvalue和派发更新triggerrefvalue。
trackrefvalue()
export function trackrefvalue(ref: refbase<any>) { if (shouldtrack && activeeffect) { ref = toraw(ref) trackeffect( activeeffect, (ref.dep ??= createdep( () => (ref.dep = undefined), ref instanceof computedrefimpl ? ref : undefined, )), __dev__ ? { target: ref, type: trackoptypes.get, key: 'value', } : void 0, ) } }
triggerrefvalue()
export function triggerrefvalue( ref: refbase<any>, dirtylevel: dirtylevels = dirtylevels.dirty, newval?: any, ) { ref = toraw(ref) const dep = ref.dep if (dep) { triggereffects( dep, dirtylevel, __dev__ ? { target: ref, type: triggeroptypes.set, key: 'value', newvalue: newval, } : void 0, ) } }
总结
ref的原理也是这样,依赖收集trackrefvalue和派发更新triggerrefvalue
到此这篇关于vue3利用自定义ref实现防抖功能的文章就介绍到这了,更多相关vue3 ref防抖内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论