如何对 vue.js 观察者使用 settimeout?

How to use settimeout with vue.js watchers?

我的应用程序中有搜索字段的自定义观察器:

watch: {
  search (query) {
    if(query.length > 2) {
      axios.post(url, query)
        .then(res => {
          console.log(res)
        })
        .catch(error => {
          console.log(error)
        })
    }
  }
}

如您所见,在我的例子中,我已经向服务器发送了关于 search var 的每个更改值的请求。我厌倦了将我的代码粘贴到 setTimeout 中,但是当用户输入 3 次时,请求也发送了 3 次而不是一次。我需要在用户输入时等待,并在停止输入后向服务器发送一个请求。

setTimeout(function () { 
    // request code here
}, 3000);

如何在 vue.js 观察者中正确地做到这一点?

您可以在 lodash 中使用 debounce。它非常适合您的用例。

import _ from lodash

watch: {
    search (query) {
        this.performSearch(query)
    }
},
methods: {
    performSearch: _.debounce(function(query) {
        axios.post(url, query)
        .then(res => {
          console.log(res)
        })
        .catch(error => {
          console.log(error)
        })
    }, 200)
}

如果想在没有lodash库的情况下实现,可以试试

data() {
    return {
        timeoutQuery: null
    }
},
watch: {
    search (query) {
        if (this.timeoutQuery) { clearTimeout(this.timeoutQuery) }
        this.timeoutQuery = setTimeout(this.performSearch(query), 300)
    }
},
methods: {
    performSearch(query) {
        axios.post(url, query)
        .then(res => {
          console.log(res)
        })
        .catch(error => {
          console.log(error)
        })
    }
}

您应该使用任何标志来表示您的请求正忙:

    data () {
        return {
          isRequestBusy: false
        }
      },
    watch: {
      search (query) {
        if(query.length > 2 && !this.isRequestBusy) {
            this.isRequestBusy = true
            axios.post(url, query)
              .then(res => {
                console.log(res)
              })
              .catch(error => {
                console.log(error)
              })
              .finally(() => {
                this.isRequestBusy = false
              })
          }
        }
      }

您可以使用箭头函数并将您的代码放入其中。

data() {
  return {
    query: "",
    queryTimeout: null
  };
},
watch: {
  query(newValue, oldValue) {
    console.log(newValue, oldValue);
    const timer = 500;  // In miliseconds
    if (this.queryTimeout) {
      clearTimeout(this.queryTimeout);
    }
    setTimeout(() => {
      this.fetchData(newValue)
    }, timer);
  }
},
methods: {
  fetchData(query = null) {
    console.log(query);
    // Put your logic code here
  }
}

有关解决此问题的更多方法,请查看此 link。