【问题标题】:Debouncing/throttling a method using Vue Class Component Syntax使用 Vue 类组件语法对方法进行去抖动/节流
【发布时间】:2020-03-14 20:00:14
【问题描述】:

我正在开发一个组件,该组件会在搜索栏中的文本发生更改时查询外部 API,并且我正在尝试消除该查询的抖动,使其只能每 2 秒执行一次。我正在尝试使用 lodash 的 debounce 函数来做到这一点,并且发现了多个博客文章和关于将它与 Vue 组件一起使用的 SO 问题,但事情很复杂,因为我使用的是 Typescript 和 Vue 类组件语法 (https://class-component.vuejs.org/ )。老实说,我对这两个都很陌生。

我找到了a blog post outlining how to do this with object-based Vue component syntax,但它不适用于类组件语法。基于对象的语法允许您将方法包装在 _.debounce 中,如下所示:

export default {
  methods: {
    throttledMethod: _.debounce(() => {
      console.log('I only get fired once every two seconds, max!')
    }, 2000)
  }
}

有没有办法用 Vue 类组件语法做类似的事情?

这是我的代码的相关部分(没有任何反跳尝试):

<template>
  <input
    v-model="searchQuery"
    @keydown="doSearch"
  >
</template>

<script lang="ts">
import axios from 'axios';
import _ from 'lodash';
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class FooSearch extends Vue {
  // data
  searchQuery = '';
  results = [];

  // methods
  async doSearch() {
    try {
      const response = await axios.get('https://api.example.org/search', {
        params: {
          query: this.searchQuery,
        }
      });

      this.results = response.data.results;
    } catch(error) {
      console.log('error');
      console.log(error);
    }
  }
</script>

【问题讨论】:

标签: typescript vue.js lodash vue-class-components


【解决方案1】:

已经讨论过here

基本上,您需要定义基本函数(就像您对 doSearch 所做的那样),然后定义新的去抖动函数:

public doSearchDebounced = _.debounce(this.doSearch, 2000)

现在你只需要拨打doSearchDebounced而不是doSearch

【讨论】:

    【解决方案2】:

    虽然上面已经回答了,但我认为我们应该在vue-class-component中善用createDecorator,并整合lodash来简化Debounce和Throttle的使用。

    创建装饰器.ts

    
    import { createDecorator } from "vue-class-component";
    import _ from "lodash";
    
    export const Debounce = (waitMs: number) =>
      createDecorator((options, key) => {
        if (options.methods && options.methods[key]) {
          const originalMethod = options.methods[key];
          const debounceMethod = _.debounce(originalMethod, waitMs, {
            leading: false,
            trailing: true,
          });
    
          options.methods[key] = async function (...args: any) {
            await debounceMethod.apply(this, args);
          };
        }
      });
    
    export const Throttle = (waitMs: number) =>
      createDecorator((options, key) => {
        if (options.methods && options.methods[key]) {
          const originalMethod = options.methods[key];
          const throttleMethod = _.throttle(originalMethod, waitMs, {
            leading: true,
            trailing: false,
          });
    
          options.methods[key] = async function (...args: any) {
            await throttleMethod.apply(this, args);
          };
        }
      });
    

    重构代码并使用装饰器。

    <template>
      <input
        v-model="searchQuery"
        @keydown="doSearch"
      >
    </template>
    
    <script lang="ts">
    import axios from 'axios';
    import { Component, Vue } from 'vue-property-decorator';
    import { Debounce } from "@/decorator";
    
    @Component
    export default class FooSearch extends Vue {
      // data
      searchQuery = '';
      results = [];
    
      // add the Debounce annotation
      @Debounce(1500)
      async doSearch() {
        try {
          const response = await axios.get('https://api.example.org/search', {
            params: {
              query: this.searchQuery,
            }
          });
    
          this.results = response.data.results;
        } catch(error) {
          console.log('error');
          console.log(error);
        }
      }
    </script>
    

    【讨论】:

      【解决方案3】:

      你可以这样做

      <script lang='ts'>   
       import { debounce } from 'decko'
      
      @debounce(1000)
       async doSearch() {
      ....
      }
      </script>
      

      【讨论】:

        猜你喜欢
        • 2017-07-08
        • 2016-10-01
        • 2015-06-24
        • 2021-07-09
        • 2018-02-16
        • 1970-01-01
        • 2015-07-25
        • 2019-11-11
        • 2015-11-22
        相关资源
        最近更新 更多