【问题标题】:Vue input event not capturing entire fieldVue输入事件未捕获整个字段
【发布时间】:2020-01-02 07:09:39
【问题描述】:

我有一个添加搜索栏和搜索栏功能的 vue 组件。它包含这一行:

<input class="input" type="text" placeholder="Address" v-model="searchQuery" v-on:input="(event) => this.$emit('queryChange', event)">

这会捕获搜索栏中的文本并发出它。

在我的 vue 中,这会触发我的 updateSearchQuery 函数: this.searchQuery = event.data 仅将用户输入保存在我的 vue 中的 searchQuery 属性中。当我这样做时一切正常,直到我进行搜索,然后使用相同的 this.searchQuery 数据进行另一个调用。

例如,我正在尝试使用搜索查询“956”过滤结果。我输入它并进行此调用:GET /users?cp=1&amp;pp=20&amp;se=956,就像它应该的那样。然后在页面加载后,如果我转到结果的第 2 页,这是对服务器的调用:GET /users?cp=2&amp;pp=20&amp;se=6。而不是将 956 保存为视图中的 queryStr,它只保存最近输入的字符,而不是搜索文本的全部内容

每次我输入多个字符作为搜索查询,然后使用未更改的this.searchQuery 变量再次调用服务器时,都会发生这种情况。如果我的初始搜索查询只有一个字符,它就可以正常工作。

我在这里做错了什么?在进行任何更改后,如何在搜索栏中发出全部文本,以便始终保存整个搜索查询,而不是仅保存最近的更改?

编辑:我在下面添加了更多代码,以便更容易理解数据流:

这是搜索组件的模板和脚本:

<template>
  <div class="level-item">
    <div class="field has-addons">
      <div class="control">
        <input class="input" type="text" placeholder="Address" v-model.lazy="searchQuery" v-on:input="(event) => this.$emit('queryChange', event)">
      </div>
      <div class="control">
        <div class="button is-light" @click="clearInput">
                    <span class="icon is-small">
                        <i class="fa fa-times" style="color:#ffaaaa"></i>
                    </span>
        </div>
      </div>
      <div class="control">
        <button class="button is-info" @click="onSearch(searchQuery)">Search</button>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Search',
    props: {onSearch: Function},
    data () {
      return {
        searchQuery: ''
      }
    },
    watch: {},
    methods: {
      clearInput () {
        this.searchQuery = ''
      }
    }
  }
</script>

发出的 queryChange 事件在 vue 页面中被捕获和监听: &lt;Search :onSearch="onSearch" v-on:queryChange="updateSearchQuery"&gt; 这会触发 updateSearchQuery 函数:

updateSearchQuery (event) {
        this.searchQuery = event.data
        console.log(event.data + '  ||  event.data')
        console.log(this.searchQuery + '  ||  this.searchQuery')
      }

理论上,我的 vue 中的 searchQuery 数据应该是我的组件中 searchQuery 数据的副本,它本身只是用户在搜索栏中输入的任何内容的副本。

然后,当我调用服务器时,我在我的 vue 中使用 this.searchQuery 中的值:

onSearch (search) {
   this.makeServerQuery(1, search)
},
onPaginate (page) {
   this.makeServerQuery(page, this.searchQuery)
},
makeServerQuery (page = null, search = null) {
   let queryStr = ''
   if (page !== null) {
       queryStr += '?cp=' + page + '&pp=' + this.perPage
   }
   if (this.searchQuery !== '') {
       queryStr += '&se=' + this.searchQuery
   }   .....

只要按下搜索按钮,就会调用 on onSearch(search) 函数。这似乎工作正常,因为当按下按钮时,整个 searchQuery 都会被传递,而不仅仅是最后一次更改。

【问题讨论】:

    标签: vue.js binding vue-component v-model


    【解决方案1】:

    输入事件的data 值似乎是最后输入的字符,而不是输入的当前值。一个简单的解决方法是:

    @input="$emit('queryChange', searchQuery)"

    这是可行的,因为模型总是会在输入事件处理程序运行之前更新。

    这是一个完整的工作组件示例:

    <input
      v-model="searchQuery"
      type="text"
      placeholder="Address"
      @input="onInput"
    />
    
    export default {
      data() {
        return { searchQuery: '' };
      },
      methods: {
        onInput() {
          console.log(this.searchQuery);
          this.$emit('queryChange', this.searchQuery);
        },
      },
    };
    

    【讨论】:

    • 进行这些更改会导致发出的所有数据都等于undefined
    • 它应该导致发出的值是一个字符串而不是一个对象。您的updateSearchQuery 需要类似于this.searchQuery = event 而不是this.searchQuery = event.data(我建议重命名这些变量)。
    • 我肯定会更改名称,只是在我这样做之前尝试让它工作。我将 event.data 改回了 event,以捕获一个字符串,但没有发送任何内容,我正在使用您上面建议的 @input 语法。 console.log(event + ' || event')console.log(this.searchQuery + ' || this.searchQuery') 均不返回任何内容。
    • 我希望您通过登录组件本身而不是父组件来调试它。请使您的组件看起来像示例中的更新代码。现在它记录了正确的值吗?
    • 是的,解决了它。当我在 v-model 上使用 .lazy 时,它不起作用,但在您进行更改后它会起作用。感谢您的帮助!
    猜你喜欢
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多