How to implement anti shake operation with multiple input search boxes in Vue.js page (use the correct posture of debounce)

Keywords: Javascript Vue Programming TypeScript

original text from Naughty kid Published in Bloghome blog

About debounce

Debounce is a very useful function in the lodash library. When implementing dynamic query of search box input, we need to prevent the front end from sending query requests to the back end frequently. At this time, we need to use debounce, which can set a time interval, such as 300ms, and ignore the input changes within 300ms. The detailed introduction of debounce can be referred to This article Article.

Advanced use of debounce

There are three search boxes in the blogger's page. Each search box needs to dynamically respond to the user's input and query the matching articles in the background, as shown in the following figure:

How to implement the debounce binding of multiple search boxes in Vue.js? The blogger will take you to have a look:

1. Monitor input variables

In the above figure, you can see that I have three input boxes, each of which needs to set a variable to save the user's input:

    data () {
      return {
        // List of articles available
        columnItems: [],
        // Loading or not
        isLoading: [false, false, false],
        // Select box search entered value
        searchColumn1: '',
        searchColumn2: '',
        searchColumn3: ''
      }
    },

Next, we bind the input variable to the input box. The blogger here uses the combobox of vuetify. If you use the html native input box or the input elements of other frameworks, please modify it slightly:

        <label>Recommended column 1</label>
        <v-combobox
          :items="columnItems"
          :loading="isLoading[0]"
          :search-input.sync="searchColumn1"
          ...
        >
        ...
        </v-combobox>
        <label>Recommended column 2</label>
        <v-combobox
          :items="columnItems"
          :loading="isLoading[1]"
          :search-input.sync="searchColumn2"
          ...
        >
        ...
        </v-combobox>
        <label>Recommended column 3</label>
        <v-combobox
          :items="columnItems"
          :loading="isLoading[2]"
          :search-input.sync="searchColumn3"
          ...
        >
        ...
        </v-combobox>

Then, I need to listen to these variables. If it changes, I will call ajax for background query:

    watch: {
      searchColumn1 (val) {
        this.getColumns(val, 0)
      },
      searchColumn2 (val) {
        this.getColumns(val, 1)
      },
      searchColumn3 (val) {
        this.getColumns(val, 2)
      }
    },
    ...
    methods: {
      getColumns: function (searchValue, index) {
        // Items have already been requested
        if (this.isLoading[index]) return
        this.isLoading[index] = true

        let vm = this
        let options = {
          page: 1
        }

        if (searchValue) {
          options.title = searchValue.trim()
        } else {
          vm.columnItems = []
          vm.isLoading[index] = false
          return
        }

        // console.log(options)
        vm.$store.dispatch('getAllColumns', options).then(function (columns) {
          if (columns && columns.length) {
            vm.columnItems = columns
          }
          vm.isLoading[index] = false
        })
      }
    }

 

2. Add debounce binding

So far, we haven't added debounce, and the above logic is fully functional. However, after running, you will find that the input operation is not smooth. If you open dev tools to view the background call, you will find that a long string of ajax calls are started after the user's input. So we introduce debounce. Here, we just need to submit the function containing the ajax call to debounce and tell it to perform the anti shake operation on the getColumns() function. And where to call debounce is very particular. The wrong introduction position will make debounce ineffective. Remember, debounce needs to be introduced in the created() hook.

    import _ from 'lodash'
    ...
    created: function () {
      this.getColumns = _.debounce(this.getColumns, 500)
    },

Finally, the blogger wants to throw out a small question: "why do we have to call debounce in created() hook, mounted() or something else?" Please leave a message or send a comment to me.
 

Reference material

 

More featured articles

Posted by Iokina on Thu, 31 Oct 2019 23:31:24 -0700