Как отличить ввод пользователя от изменения данных с помощью 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>

Как видите, я хочу сохранить продукт, когда пользователь изменяет значения в этом множественном выборе. Работает нормально, но с одной проблемой.

Значение выбора привязано к данным product.recommended_accessories. В другом месте приложения продукт загружается с сервера, который включает атрибут recommended_accessories. Затем загрузка продукта запускает saveProduct для вызова, поскольку vue-select устанавливает предварительно выбранные параметры для ввода, что, по-видимому, запускает событие @input.

Есть ли что-нибудь вокруг этого? Может, здесь я допустил какую-то дизайнерскую ошибку. Или, может быть, есть ловушка, которую я должен использовать для привязки обработчика событий или для установки какого-то флага, указывающего, что продукт находится в процессе загрузки и сохранение продукта не должно происходить.

Я просто стараюсь не сохранять товар сразу после загрузки без причины.


person flyingL123    schedule 20.04.2018    source источник


Ответы (2)


На данный момент я просто отслеживаю переменную accessoryEventCount, которая инициализируется значением 0 при загрузке продукта. Затем я проверяю accessoryEventCount > 0 перед вызовом saveProduct в событии v-select input.

Это работает, но мне все еще интересно, есть ли более элегантное решение.

ОБНОВЛЕНИЕ

Похоже, что Vue.nextTick - это то, что я искал. Перед установкой значения продукта в коде я установил флаг this.isSettingProduct = true. Затем устанавливаю товар и звоню Vue.nextTick(() => { this.isSettingProduct = false });.

Теперь я могу не сохранять товар, если this.isSettingProduct == true. Использование Vue.nextTick гарантирует, что флаг не будет возвращен в значение false до завершения асинхронного обновления данных.

person flyingL123    schedule 20.04.2018

Похоже, вам следует привязать prop = onChange, хотя @input все еще работает (проверьте v-select github: line # 544).

Ниже приведено мое решение: перед загрузкой вашего продукта привяжите onChange с function () {}, после загрузки привяжите его с функцией, которая вам нравится.

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>

person Sphinx    schedule 20.04.2018