最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use settimeout with vue.js watchers? - Stack Overflow

programmeradmin2浏览0评论

I have custom watcher for search field in my application:

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

Here as you see I've send request to server on everey change value of search var in my case. I tired paste my code inside setTimeout but when user typing 3 time then requests too sent 3 times instead of one time. I need to wait when user is typing and after stop typing send one request to server.

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

How I can do it correctly inside vue.js watchers?

I have custom watcher for search field in my application:

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

Here as you see I've send request to server on everey change value of search var in my case. I tired paste my code inside setTimeout but when user typing 3 time then requests too sent 3 times instead of one time. I need to wait when user is typing and after stop typing send one request to server.

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

How I can do it correctly inside vue.js watchers?

Share Improve this question asked Jul 22, 2019 at 5:00 Andreas HunterAndreas Hunter 5,03418 gold badges75 silver badges144 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

You can use debounce in lodash. It's perfect for your usecase.

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)
}

If you want to implement it without lodash library, you can try

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)
        })
    }
}

You should use any flag to indicate than your request is busy:

    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
              })
          }
        }
      }

You can use the arrow function and put your code inside of it.

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
  }
}

For more way to solve this problem, check this link. https://stackoverflow./a/38431406/4494207

发布评论

评论列表(0)

  1. 暂无评论