cqwcns 发表于 2023-1-21 22:22

vue3,如何利用customRef 实现函数执行防抖

本帖最后由 cqwcns 于 2023-1-21 22:28 编辑

我希望点击按钮触发myFun函数,但如果2秒内多次点击,最终只会执行一次myFun。
我留意到vue3有个customRef 方法是实现input防抖的,有没有办法改一下,实现函数执行防抖,请各位大佬指教,感谢。


<template>

<button @click="toAction">触发</button>

</template>

<script setup>
import { customRef } from 'vue'

function useDebouncedRef(value, delay = 200) {
let timeout
return customRef((track, trigger) => {
    return {
      get() {
      track()
      return value
      },
      set(newValue) {
      clearTimeout(timeout)
      timeout = setTimeout(() => {
          value = newValue
          trigger()
      }, delay)
      }
    }
})
}

const myFun = () => {
console.log('函数执行了')
}

const toAction = () => {
console.log('触发了');
useDebouncedRef(myFun, 2000)
}

</script>

使用场景说明:

正常来说,防抖主要是用于input的输入。函数执行完全加一些逻辑来实现防抖。
但实际使用的场景是element-plus select-v2组件(远程搜索),它有个input动态生成的,无法使用一般的input防抖。
所以考虑从在远程搜索函数上进行防抖。

Goldrepo 发表于 2023-1-22 00:00

github上面没有相关案例可以参考吗?

Qin77 发表于 2023-1-22 00:02

不错啊,有我理解一半

steven026 发表于 2023-1-22 00:14

let lastClick=0
const toAction = () => {
console.log('触发了');
const now=Date.now();
if(now - lastClick < 2000) return //防抖 本次点击-上次点击<2000
lastClick=now;
useDebouncedRef(myFun, 2000)
}
自己实现一个就行了,就几行,利用Date.now()对比2次点击时间差

啊笨 发表于 2023-1-22 10:31

高手,学习了!

索马里的海贼 发表于 2023-1-22 10:51

用rxjs吧,一把梭~

我去年买了各表 发表于 2023-1-22 18:49

iLouis 发表于 2023-1-27 18:59

一般来说,防抖都是自己写,没几句的事情。


// 防抖对象
function debounce(fnRun, interval, fnRe) {
    let timer = 0;
    return (...args) => {
      let realInterval = new Date() - timer
      // 这里也可以把间隔传回去,比如要搞个提示之类的
      if (realInterval < interval) return fnRe ? fnRe.apply(null, args) : false
      timer = +new Date();
      // 这里也可以把当前时间戳传回去,比如要发给服务器
      fnRun.apply(null, args)
    }
}

// 测试绑定
let myOnChange = new debounce(
    inputText => console.log(`run: ${inputText}`),
    2000,
    inputText => console.log(`return: ${inputText}`)
)

// 测试输入
setInterval(() => {
    myOnChange('inputText')
}, 500)


当然也可以根据es5、es6、ts规则改成class之类的。
也可以把返回函数改成promise之类的

如果不是很需要这个,直接外面一个全局new Date,里面一个new Date,<间隔直接return,也是可以的。
页: [1]
查看完整版本: vue3,如何利用customRef 实现函数执行防抖