更改v-model值时如何防止@change事件

Cap*_*row 6 vuejs2

我正在 Vue.js 中构建一个由 Firebase 支持的自动完成菜单(使用 vue-fire)。目的是开始输入用户的显示名称并在下面的 div 列表中显示匹配记录。

模板如下所示:

<b-form-input id="toUser"
    type="text"
    v-model="selectedTo"
    @change="searcher">
</b-form-input>

<div v-on:click="selectToUser(user)" class="userSearchDropDownResult" v-for="user in searchResult" v-if="showSearcherDropdown">{{ user.name }}</div>
Run Code Online (Sandbox Code Playgroud)

单击潜在匹配项后,目的是设置该字段的值并清除匹配项列表。

这是组件的代码部分:

computed: {
  /* method borrowed from Reddit user imGnarly: https://www.reddit.com/r/vuejs/comments/63w65c/client_side_autocomplete_search_with_vuejs/ */
  searcher() {
    let self = this;
    let holder = [];
    let rx = new RegExp(this.selectedTo, 'i');
    this.users.forEach(function (val, key) {
      if (rx.test(val.name) || rx.test(val.email)) {
        let obj = {}
        obj = val;
        holder.push(obj);
      } else {
        self.searchResult = 'No matches found';
      }
    })
    this.searchResult = holder;
    return this.selectedTo;
  },

  showSearcherDropdown() {
    if(this.searchResult == null) return false;
    if(this.selectedTo === '') return false;
    return true;
  }
},

methods: {
  selectToUser: function( user ) {
    this.newMessage.to = user['.key'];
    this.selectedTo = user.name;
    this.searchResult = null;
  }
}
Run Code Online (Sandbox Code Playgroud)

Typeahead 运行良好,每次更改输入字段时,都会调用 searcher() 函数并使用正确的值填充 searchResult。显示了 v-for 和 div 列表。

单击 div 后,我调用 selectToUser( user )。这可以正确地将用户对象的详细信息报告给控制台。

但是,在第一次单击时,我在控制台中遇到异常并且 div 没有清除(我希望它们消失,因为我将 searchResults 设置为 null)。

[Vue warn]: Error in event handler for "change": "TypeError: fns.apply is not a function"

found in

---> <BFormInput>
       <BFormGroup>
         <BTab>

TypeError: fns.apply is not a function
    at VueComponent.invoker (vue.esm.js?efeb:2004)
    at VueComponent.Vue.$emit (vue.esm.js?efeb:2515)
    at VueComponent.onChange (form-input.js?1465:138)
    at boundFn (vue.esm.js?efeb:190)
    at invoker (vue.esm.js?efeb:2004)
    at HTMLInputElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1802)
Run Code Online (Sandbox Code Playgroud)

如果我第二次单击 div则没有错误,输入值已设置并且 div 消失。

所以我怀疑向 this.selectedTo(这也是元素的 v-model 对象)写入一个值会触发 @change 事件。在第二次点击时,值实际上并没有改变,因为它已经设置了,所以没有调用到 searcher() 并且没有错误。

我注意到如果元素失去焦点也会发生这种情况。

问题:通过方法更改 v-model 值时如何防止 @change 事件?

(其他信息:根据 package.json 我在 vue 2.5.2)

Cap*_*row 0

@acdcjunior,感谢您的回答。

\n\n

当然,仅删除对的引用searcher()意味着对字段值更改不采取任何操作,因此该字段根本无法工作。

\n\n

searcher()函数移入methods: {}而不是意味着computed: {}它将在输入事件上被调用,甚至不会发生变化(另一个谜团,但不是今天的谜团)。一个微妙的差异消除了 I\xe2\x80\x99m 所瞄准的预输入功能。

\n\n

然而,它确实让我记住,函数的结果computed: {}是被缓存的,并且当任何参数发生变化时将重新计算。在这种情况下,我意识到该searcher()函数依赖于this.selectedTo变量。因此,当selectToUser()函数设置时this.selectedTo,它会触发另一个对searcher().

\n\n

现在修好了。如果将来有人遇到类似的问题,我通过添加另一个变量转向老式信号量来解决这个问题。

\n\n
var userMadeSelection: false\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,searcher() 首先检查这种情况:

\n\n
  computed: {\n      searcher() {\n          if(this.userMadeSelection) {\n            this.userMadeSelection = false;\n            return this.selectedTo;\n          }\n          \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在 selectToUser() 中:

\n\n
this.userMadeSelection = true;\n
Run Code Online (Sandbox Code Playgroud)\n