【问题标题】:How to debounce an AJAX call with VueJS?如何使用 VueJS 去抖动 AJAX 调用?
【发布时间】:2016-07-31 16:31:43
【问题描述】:

我正在尝试对 AJAX 调用进行去抖动以仅发送一次,但不幸的是,它告诉我我传递给它的不是函数。这是我的代码:

getItems: function(page){
  this.page = page;
  console.log(typeof(this.getBackendItems));
  _.debounce(this.getBackendItems(page), 500);
},
getBackendItems: function(page){
  this.$http.get("{{url('api/user/items')}}", {page : page}).success(function(response){
      this.items = response.data;
      this.last_page = response.last_page;
  });
},

Console.log 说 getBackendItems 是一个函数,但仍然会抛出一个错误,即没有将函数传递给 _.debounce() 调用。

【问题讨论】:

    标签: lodash vue.js


    【解决方案1】:

    这有几个问题:

    正确传递函数

    当你试图传递这样的函数时:this.getBackendItems(page) 你正在运行它,所以_.debounce 没有接收到函数,但是函数的结果,在这种情况下,是一个 Promise 对象。

    • this.getBackendItems传函数
    • this.getBackendItems(page) 运行函数,并传递结果

    但是,你如何告诉它使用哪些参数?

    正确调用去抖函数

    好吧,_.debounce() 返回您的原始函数,但包含去抖动逻辑。因此,您将其缓存在一个变量中并使用您想要的参数 (page) 执行该函数。所以使用 debounce 的语法正确的方式应该是这样的:

    getItems: function(page){
      this.page = page;
      console.log(typeof(this.getBackendItems));
      var debouncedFunction = _.debounce(this.getBackendItems.bind(this), 500); // properly bind the function so "this" is the vue component.
      debouncedFunction(page)
    },
    

    正确的函数去抖动

    但是,这也行不通,因为getItems 本身没有去抖动,所以这段代码要做的就是创建很多很多去抖动的函数,一旦 500ms 结束,它们都会触发开始。不是一个好主意。

    现在我的问题是:你如何调用这个函数?从 v-on:click?然后 Vue 为您服务:

    使用 Vue 的去抖动过滤器

    <a v-on:click="getItems(page) | debounce 500">Some Link</a>
    

    使用该过滤器,您根本不需要使用_.debounce

    如果您以其他方式调用此函数,请告诉我。

    编辑:由于评论反馈而更新:

    debounce 函数同时计算 debounce 次数

    <a href="#"
      @click.prevent="getItems(page) | debounce 500" 
      @click="pageBuffer = pageBuffer +1">
      Click Me
    </a>
    

    JS:

    var App = new Vue({
      el: '#app',
      data() {
        return {
                page: 1,
          pageBuffer: 0
        }
      },
      methods: {
        getItems: function(page) {
          this.getBackendItems(page + this.pageBuffer)
          this.pageBuffer = 0
        }
      }
    })
    

    【讨论】:

    • 我有一个链接 Some Link。注意“page + 1”。如果我将去抖过滤器放在上面 - 页面不会发生变化,因为它被放置在将被去抖的函数内。我需要的是立即更改页面,但只加载最后一个。就像用户在第 1 页并单击“下一步”4 次一样,我需要它将“current_page”增加 4 次,所以它是 5,但只加载项目一次 - 对于第 5 页。
    • 我无法描述您的确切情况,但您可以使用第二个(未去抖动的)点击处理程序来单独增加一些缓冲区变量以用于额外的点击。看到这个小提琴:jsfiddle.net/Linusborg/z14zmw16
    • 我自己也想过类似的事情,但是放置两个 @click 处理程序对我来说似乎很尴尬。如果这是唯一的解决方案,我会同意的。
    • 顺便说一句,如果 AJAX 请求失败,我可以简单地清空页面缓冲区,这样用户就会看到他的点击无效:)
    • 去抖过滤器已在新的 vue 版本中被移除。
    【解决方案2】:

    以下是适合我的解决方案:

    <template>
      <div>
        <input type="text" v-model="term">
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          term: ''
        }
      },
    
      watch: {
        term(value) {
          this.search(value)
        }
      },
    
      mounted() {
        this.search = _.debounce(this.getBackendItems.bind(this), 1000)
      },
    
      methods: {
        getBackendItems(value) {
          console.log(value)
          // ...
        }
      }
    }
    </script>
    

    【讨论】:

      猜你喜欢
      • 2020-07-22
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 2018-02-16
      相关资源
      最近更新 更多