当前位置: 代码网 > it编程>编程语言>Javascript > Vue3利用自定义ref实现防抖功能

Vue3利用自定义ref实现防抖功能

2024年06月11日 Javascript 我要评论
<script setup>import { debounceref } from './ref'; const text = debounceref('',1000)</scrip
<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防抖内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com