如何使用vue-select区分用户输入和数据更改

时间:2018-04-20 20:11:17

标签: javascript vue.js vue-select

我在我的应用中使用了vue-select,并尝试阻止在默认值首次加载到vue-select输入时触发事件处理程序。

该组件如下所示:

<v-select
    multiple
    v-model="product.recommended_accessories"
    label="name"
    :options="accessoryOptions"
    @input="saveProduct"
    @search="onAccessorySearch">
        <template slot="option" slot-scope="option">
            <h4>{{ option.name }}</h4>
            <h5>{{ option.sku }}</h5>
        </template>
</v-select>

如您所见,我想在用户更改此多选中的值时保存产品。它工作正常,但有一个问题。

select的值与product.recommended_accessories数据相关联。在应用程序的其他位置,从服务器加载产品,其中包含recommended_accessories属性。加载产品然后触发saveProduct被调用,因为vue-select设置输入的预选选项,这显然会触发@input事件。

这周围有吗?也许我在这里犯了某种设计错误。或者可能有一个钩子我应该用来绑定事件处理程序,或设置某种标志,表明产品正在加载过程中,并且不应该保存产品。

我只是试图避免在产品无故装入后立即保存产品。

2 个答案:

答案 0 :(得分:1)

现在,我只是跟踪一个accessoryEventCount变量,只要加载产品,该变量就会被初始化为0。然后,在v-select accessoryEventCount > 0事件上调用saveProduct之前,请确保input

它有效,但我仍然想知道是否有更优雅的解决方案。

<强>更新

看起来Vue.nextTick就是我想要的。在代码中设置product的值之前,我设置了一个标志this.isSettingProduct = true。然后我设置了产品,并致电Vue.nextTick(() => { this.isSettingProduct = false });

现在我可以避免在this.isSettingProduct == true时保存产品。使用Vue.nextTick可确保在异步数据更新完成之前,该标志不会设置为false。

答案 1 :(得分:0)

看起来你应该绑定prop = onChange,虽然@input似乎仍然有用(检查v-select github: line# 544)。

以下是我的解决方案,在加载产品之前,使用function () {}绑定onChange,加载后,将其与您喜欢的函数绑定。

Vue.component('v-select', VueSelect.VueSelect)

app = new Vue({
  el: "#app",
  data: {
    accessoryOptions: [
      {'name':'a1', 'sku':'a2'},
      {'name':'b1', 'sku':'b2'},
      {'name':'c1', 'sku':'c2'}
    ],
    product: {
      recommended_accessories: []
    },
    saveProduct: function (){}
  },
  methods: {
    onAccessorySearch: function () {
      console.log('emit input')
    },
    loadProduct: function () {
      this.product.recommended_accessories = ['a1', 'b1'] // simulate get data from the server
      setTimeout( () => {
        this.saveProduct = (value) => {
          console.log('emit input', this.product.recommended_accessories)
        }
      }, 400)
    }
  }
})
#app {
  width: 400px;
}
<script src="https://unpkg.com/vue@latest"></script>
<script src="https://unpkg.com/vue-select@latest"></script>
<div id="app">
  <button @click="loadProduct()">Click Me!</button>
  <v-select
      multiple
      v-model="product.recommended_accessories"
      label="name"
      :options="accessoryOptions"
      :on-change="saveProduct"
      @search="onAccessorySearch">
          <template slot="option" slot-scope="option">
              <span>{{ option.name }}</span>
              <span>{{ option.sku }}</span>
          </template>
  </v-select>
</div>