Vue自定义指令实现防抖/节流

5,657 阅读2分钟

防抖和节流大家都再熟悉不过了,随便网上搜搜都是几十上百万的结果。

微信截图_20210729162113.png

首先声明本文不会手写防抖和节流,将直接采用Lodash提供的现成debounce和throttle,要想了解防抖和节流怎么实现的同学可以去看看源码和很多很多大佬的优秀文章,相信聪明的你一看就懂!

言归正传,自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。所以我们会想到使用自定义指令来实现这两个方法。废话不多说,我们直接上代码,拿来吧你!

import _debounce from 'lodash/debounce'
let fn = null
const debounce = {
  inserted: function(el, binding) {
    fn = _debounce(binding.value, 2000, {
      leading: true,
      trailing: false
    })
    el.addEventListener('click', fn)
  },
  unbind: function(el) {
    fn && el.removeEventListener('click', fn)
  }
}
export default debounce

太清晰了,一目了然!这里的insertedunbind都是一个指令定义对象的钩子函数:

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • unbind:只调用一次,指令与元素解绑时调用。 钩子函数中的参数:

el:指令所绑定的元素,可以用来直接操作 DOM。

binding:一个对象。

所以我们在inserted里面把引入的debounce方法配置好并添加到click事件内,那么我们就完成了80%了。

紧接着我们新建一个index.js文件,把我们的指令引入并注册一下。

import debounce from './debounce'

const install = function(Vue) {
  Vue.directive('debounce', debounce)
}

if (window.Vue) {
  window['debounce'] = debounce
  Vue.use(install); // eslint-disable-line
}

debounce.install = install
export default debounce

最后在main.js中引入就可以直接用啦

import debounce from '@/directive/debounce'
Vue.use(debounce)
// 简单的小例子,up就是需要实现防抖的方法
<button v-debounce="up">点我呀!</button> 

节流的方法和防抖是一样的,只需要换个指令名,引入的Loadsh方法将debounce改为throttle即可,是不是炒鸡简单!