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

时间:2018-02-26 09:36:52

标签: vuejs2

我正在Firebase支持的Vue.js中构建一个自动完成菜单(使用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>

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

以下是组件的代码部分:

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;
  }
}

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

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

然而,在第一次点击时我在控制台中得到一个异常并且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)

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

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

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

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

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

1 个答案:

答案 0 :(得分:0)

@acdcjunior,谢谢你的回答。

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

searcher()函数移动到methods: {}而不是computed: {}意味着它将在输入事件上调用而不是更改甚至(另一个神秘但今天不是一个)。一个微妙的差异,消除了我瞄准的先行功能。

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

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

var userMadeSelection: false

现在,搜索者()首先检查这种情况:

  computed: {
      searcher() {
          if(this.userMadeSelection) {
            this.userMadeSelection = false;
            return this.selectedTo;
          }
          …

然后在selectToUser()中:

this.userMadeSelection = true;