zoukankan      html  css  js  c++  java
  • 在 Vue 中使用lodash对事件进行防抖和节流,防止用户重复点击按钮提交

    一、防抖函数手动写

    防抖函数定义:一个需要频繁触发的函数,在规定时间内只让最后一次生效,前面的不生效

    /**
     * @param {*} fn 包装的事件回调函数
     * @param {*} delay 等待时间
     */
    
    export function debounce(fn, delay) {
      // 记录上一次的延时器
      var timer = null
      // 将debounce处理结果当作函数返回
      return () => {
        // 保留调用时的this上下文
        let context = this
        // 保留调用时传入的参数
        let args = arguments
    
        // 每次事件被触发时,都去清除之前的旧定时器
        if (timer) {
          clearTimeout(timer)
        }
        // 重新设置新的延时器
        timer = setTimeout(() => {
          // 解决this指向问题
          fn.apply(context, args)
        }, delay)
      }
    }
    // 用debounce来包装scroll的回调
    const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)

    注意:debounce 的问题在于它“太有耐心了”。试想,如果用户的操作十分频繁——他每次都不等 debounce 设置的 delay 时间结束就进行下一次操作,于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感

    用 Throttle 来优化 Debounce

    // fn是我们需要包装的事件回调, delay是时间间隔的阈值
    function throttle(fn, delay) {
      // last为上一次触发回调的时间, timer是定时器
      let last = 0, timer = null
      // 将throttle处理结果当作函数返回
      
      return function () { 
        // 保留调用时的this上下文
        let context = this
        // 保留调用时传入的参数
        let args = arguments
        // 记录本次触发回调的时间
        let now = +new Date()
        
        // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
        if (now - last < delay) {
        // 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器
           clearTimeout(timer)
           timer = setTimeout(function () {
              last = now
              fn.apply(context, args)
            }, delay)
        } else {
            // 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应
            last = now
            fn.apply(context, args)
        }
      }
    }
    
    // 用新的throttle包装scroll的回调
    const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
    
    document.addEventListener('scroll', better_scroll)

    二、在 Vue 里使用 lodash 中的 Debouncing 和 Throttling

    安装

    可以通过 yarn 或 npm 安装 lodash。

    # Yarn
    $ yarn add lodash
    # NPM
    $ npm install lodash --save

    注意:如果我们不想导入lodash的所有内容,而只导入所需的部分,则可以通过一些Webpack构建自定义来解决问题。 还可以使用lodash.throttlelodash.debounce等软件包分别安装和导入lodash的各个部分。

    throttling 方法

    要对事件进行节流处理方法非常简单,只需将要调用的函数包装在lodash的_.throttle函数中即可。

    <template>
      <button @click="throttledMethod()">Click me as fast as you can!</button>
    </template>
    
    <script>
    import _ from 'lodash'
    
    export default {
      methods: {
        throttledMethod: _.throttle(() => {
          console.log('I get fired every two seconds!')
        }, 2000)
      }
    }
    </script>

    debouncing 方法

    尽管节流在某些情况下很有用,但一般情况我们经常使用的是防抖。 防抖实质上将我们的事件分组在一起,并防止它们被频繁触发。 要在Vue组件中使用节流,只需将要调用的函数包装在lodash的_.debounce函数中。

     
    <template>
      <button @click="throttledMethod()">Click me as fast as you can!</button>
    </template>
    
    <script>
    import _ from 'lodash'
    
    export default {
      methods: {
        throttledMethod: _.debounce(() => {
          console.log('I only get fired once every two seconds, max!')
        }, 2000)
      }
    }
    </script>
  • 相关阅读:
    详解Bootstrap进度条组件
    详解Bootstrap缩略图组件及警示框组件
    详解Bootstrap表单组件
    spring注解-@Autowired。@Resource。@Service
    spring注解-@Transactional事务几点注意
    17_8_9 Spring 注入
    MySQL常用语句
    Mysql 远程登录及常用命令
    数据库(外键及其约束理解)
    C语言队列(数组内核)
  • 原文地址:https://www.cnblogs.com/chen-cheng/p/12795445.html
Copyright © 2011-2022 走看看