自定义指令,封装节流、防抖等常用untils

861 阅读3分钟

背景

项目中,常用到一些utils,像深拷贝、数组去重、函数的节流防抖等。引入lodash,基本就覆盖绝大多数场景了。 但也一种新思路,就是vue自定义指令

这里记录一下,自定义指令节流和防抖。

官网对自定义指令介绍

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

官网链接地址 cn.vuejs.org/v2/guide/cu…

代码实现

防抖

事件触发后,开始倒计时,倒计时结束函数执行;如果倒计时期间再次触发 则重新开始倒计时

用于:按钮的防重提交输入框的延时保存输入框输入查询机顶盒输入频道切换等场景

新建src/directive/debounce.js

import Vue from 'vue'
/**
 * 防抖 就是指触发事件后在  特定间隔内 函数只能执行一次,如果在时间间隔内又触发了事件,则会重新计算函数执行时间
 *三个入参 响应函数名 时长 绑定事件名
 *  v-debounce="['addF',1000,'click']"  
 */
Vue.directive('debounce', {
  inserted: function (el, bindingObj) {
    let timer //定义计时器对象
    let [fn, time = 300, attr = 'click'] = bindingObj.value //解构取值 时间默认300毫秒 绑定事件默认click
    el.addEventListener(attr, () => {
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => fn(), time)
    })
  }
})

main.js 引入一下

import "@/directive/debounce.js"

test.vue

<van-button type="info" v-debounce="[addF,1000]">点击测试debounce</van-button>

节流

事件持续触发,特定时间内只执行一次。让一个函数不要执行得太频繁,无论事件触发多少次,也就回调一次

用于鼠标不断点击触发mousedown(单位时间内只触发一次)监听滚动事件,滚动条位置懒加载机顶盒,多次按频道或音量加减键

新建throttle.js

import Vue from 'vue'
/**
 * 节流  持续触发某个事件 特定时间间隔内只执行一次
 *三个入参 响应函数名 时长 绑定事件名
 *  v-throttle="['addF',1000,'click']"  
 */
Vue.directive('throttle', {
  inserted: function (el, bindingObj) {
    let flag, timer
    let [fn, time = 300, attr = 'click'] = bindingObj.value //解构取值 时间默认300毫秒 绑定事件默认click
    el.addEventListener(attr, () => {
      if (flag) {
        //还没清除又触发了   就中断执行return false  重新倒计时 
        console.log('enter flag')
        clearTimeout(timer)
        timer = setTimeout(() => fn(), time)
        return false
      }
      fn()
      flag = setTimeout(() => flag = null, time) //触发后 规定时间间隔 将flag清除 
    })
  }
})

main.js 引入一下

import "@/directive/throttle.js"

test.vue

 <van-button type="info" v-throttle="[delF,1000]">点击测试throttle</van-button>

仓库地址 github.com/xuhongg/van…

首页点击节流防抖进入调试页。