Vue Watch doesnt Get triggered when using axios

2019-07-19 03:21发布

Hey guys I have this code that fetches data from database usin axios, and in the .then() function I set a data property, watch doesnt trigger. Here is some code that I currently have. And thank you in advance!

export default {

    name: '..',
    data() {
        return {
            autocompleteOn: false
        }
    },

    watch: {
        autocompleteOn(oldVal, newVal) {
            console.log('autocomplet') // doesnt trigger this
        }
    },

    methods: {
        fetchAutocompleteResults: _.debounce((filter) => {
            let $this = this;



            let data = {
                filter: filter,
                page: $this.page
            };

            filter.resources.response = [];
            filter.loading = true;

            axios.post(BASE_URL + '/search/filter', data).then(function(response) {
                if (response.data.length) {
                    filter.autocompleteOn = true;
                    $this.autocompleteOn = true;
                    filter.resources.response = filter.resources.response.concat(response.data);
                    $this.currentFilter = filter;
                    $this.page++;
                    console.log($this.autocompleteOn); // this is correct
                }

                filter.loading = false;
            });
        }, 300)
    }

}

1条回答
我想做一个坏孩纸
2楼-- · 2019-07-19 04:12

The debounce with an arrow function is making the this be something other than the Vue instance (e.g. window).

Instead of:

methods: {
    fetchAutocompleteResults: _.debounce((filter) => {

Use:

methods: {
    fetchAutocompleteResults: _.debounce(function (filter) {
//                                       ^^^^^^^^        ^^^

Demo:

new Vue({
  el: '#app',
  data() {
    return {
      autocompleteOn: false
    }
  },
  watch: {
    autocompleteOn(oldVal, newVal) {
      console.log('autocomplet') // doesnt trigger this
    }
  },
  methods: {
    fetchAutocompleteResults: _.debounce(function (filter) { // CHANGED from arrow function
      let $this = this;

      let data = {
        filter: filter,
        page: $this.page
      };

      filter.resources.response = [];
      filter.loading = true;
      
      // changed data for demo
      data = [{title: 'foo', body: 'bar', userId: 1}];

      // changed URL for demo
      axios.post('https://jsonplaceholder.typicode.com/posts', data).then(function(response) {
        if (response.data.length) {
          filter.autocompleteOn = true;
          $this.autocompleteOn = true;
          filter.resources.response = filter.resources.response.concat(response.data);
          $this.currentFilter = filter;
          $this.page++;
          console.log($this.autocompleteOn); // this is correct
        }

        filter.loading = false;
      });
    }, 300)
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script>

<div id="app">
  <button @click="fetchAutocompleteResults({resources: {}})">fetchAutocompleteResults</button>
</div>

查看更多
登录 后发表回答