Vue.js-具有查询参数的搜索表单

时间:2019-05-31 00:38:53

标签: javascript vue.js

我正在将Vue.js 2.6与vue-router组件一起使用。我有一个搜索表,如下所示:

<form class="search-form" @submit.prevent="search">
    <div class="form-group">
        <input type="text" class="form-control" v-model="term" placeholder="Search">
    </div>
</form>

这是我的脚本:

<script>
  export default {
    data() {
      return {
        term: this.$route.query.term,
        items: []
      }
    },
    created() {
      if (this.term != null) {
        this.search()
      }
    },
    watch: {
      '$route.query.term'() {
        this.term = this.$route.query.term
        this.search()
      }
    },
    methods: {
      search: function () {
        window.axios.get('/images/search', {
          params: {
            term: this.term
          }
        })
        .then(response => {
          this.$router.push({query: { 'term' : this.term}})
          this.items = response.data.collection.items
        })
        .catch(error => {
          return error
        })
      }
    }
  }
</script>

我试图用这段代码实现以下内容:

  1. 用户提交表单,将调用search()函数。用查询参数更新网址,例如/search?term=<term>此功能正常,但是search()函数被调用了两次。
  2. 用户执行几次搜索,然后按返回按钮。表单中的搜索字段将更新并执行搜索。 此功能正常,但是search()函数被调用了两次。
  3. 用户在URL栏中手动输入查询参数。填写表格中的搜索字段,然后执行搜索。 这有效。

search()函数被两次调用的情况下,这归因于watch()函数,该函数旨在监视URL栏的更改。我不确定如何将该功能与search()函数正确结合。

1 个答案:

答案 0 :(得分:0)

watch中,您可以将新值与旧值进行比较,并且仅当新值与旧值不同时才执行搜索

watch: {
  '$route.query.term'(newVal, oldVal) {
    if (newVal != oldVal) {
      this.term = this.$route.query.term
      this.search()
    }
  }
},

要使其在第一种情况下仅调用1,您可能希望将按钮点击处理程序与实际搜索调用分开

<script>
  export default {
    data() {
      return {
        term: this.$route.query.term,
        items: []
      }
    },
    created() {
      if (this.term != null) {
        this.performSearch()
      }
    },
    watch: {
      '$route.query.term': {
        handler: function(newVal, oldVal) {
          if (newVal != oldVal) {
            this.term = this.$route.query.term
            this.performSearch()
          }
        },
        immediate: true 
      }
    },
    methods: {
      search: function () {
        // this is call when user click search Button
        this.$router.push({query: { 'term' : this.term}})

      },
      performSearch() {
        // perform actual searcch
        window.axios.get('/images/search', {
          params: {
            term: this.term
          }
        })
        .then(response => {
          this.items = response.data.collection.items
        })
        .catch(error => {
          return error
        })
      }
    }
  }
</script>