【问题标题】:Is it possible to detect if a change event was triggered by a click on a Vue select element?是否可以检测到单击 Vue 选择元素是否触发了更改事件?
【发布时间】:2017-10-05 19:39:13
【问题描述】:

我有一个 <select> 元素,它有一个使用 Vue 中的 v-model 绑定到它的数据属性。

有时我想动态更改该值。我还有一个附加到此元素的事件侦听器,它在change-事件上触发。见代码示例:

<template>
  <div class="mySelector">
        <select id="testSelect" v-model="mySelectModel"
                @change="onChange($event)">
          <template v-for="(item, index) in someList">
              <option :class="['btn', 'btn-default', 'removing-button']" :value="index">{{item.name}}</option>
          </template>
        </select>
  </div>
</template>

<script>

  export default {
    data() {
      return {
        mySelectModel: null
      }
    },
    props: {
    },
    methods: {
      customChange: function() {
        this.mySelectModel = ... // some value we from somewhere else that is set dynamically on some condiftion
      },
      onChange: function (event) {
        if (!event) return;
        // DO SOMETHING THAT WE ONLY WANT TO DO ON A REAL CLICK
      }
    },
  }
</script>

我遇到的问题是,当我动态更改数据值mySelectModel 时,就像在customChange-方法中一样,change 事件也被调用,触发方法onChange。如果它真的是由真正的点击触发的,我只想在那个方法中做一些事情,而不是当它被动态更改时。

change-event 由单击触发或由于其他原因而更改时,我无法找到区分这些情况的方法。有什么建议吗?

【问题讨论】:

  • 如果用作v-model 的属性发生变化,则不应调用change 事件。看到这个小提琴jsfiddle.net/gpedcsr4/1。你能举个例子吗?

标签: vue.js vuejs2


【解决方案1】:

vue-js-selected-doesnt-triggering-change-event-select-option,似乎在JS更新v-model时select不会触发@change(仅当用户更改所选值时)。

指令可以添加功能

Vue.directive('binding-change', {
  update: function (el, binding, vnode) {
    const model = vnode.data.directives.find(d => d.name === 'model')
    if (model) {
      binding.value(model.value)
    }
  }
})

使用喜欢

<select id="testSelect" 
  v-binding-change="onChange" 
  v-model="mySelectModel" 
  @change="onChange($event)">

不确定 onChange 的参数 - 我会测试一下。

【讨论】:

    【解决方案2】:

    类似于this suggested solution,您可以在您的小部件中创建一个可设置的计算您v-model

    1. get 函数只返回数据项
    2. 除了设置数据项之外,set 函数还可以执行您希望在小部件中进行更改的任何操作

    其他代码可以直接改变数据项,不会执行计算的set代码。

    new Vue({
      el: '#app',
      data: {
        values: ['one','two','three'],
        selectedItem: 'two'
      },
      computed: {
        wrappedSelectedItem: {
          get() { return this.selectedItem; },
          set(value) {
            console.log("Changed in widget");
            this.selectedItem = value;
          }
        }
      },
      methods: {
        changeToThree() {
          console.log("Stealth change!");
          this.selectedItem = 'three';
        }
      }
    });
    <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
    <div id="app">
      <select v-model="wrappedSelectedItem">
        <option v-for="value in values" :value="value">{{value}}</option>
      </select>
      <button @click="changeToThree">Set to three</button>
    </div>

    【讨论】:

    • 这是一个很好的解决方案,但它并不完全适合我。如果我确实喜欢您的示例并且有一个更改值的按钮,则不会调用 set- 方法,这是正确的。但是,当我从一些其他方法更改值时,该方法会因反应变量的某些更改而被调用,无论如何都会调用set-方法。我无法理解其中的区别。
    • 这完全取决于您更改哪个变量。如果您更改wrappedSelectedItem,将调用setter。如果你更改selectedItem,它不会。
    • 我不会改变wrappedSelectedItem。我正在更改 selectedItem 并且无论如何都会调用 setter。
    • 你能把小提琴放在一起吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    相关资源
    最近更新 更多