Как настроить «несколько» реквизитов в компоненте Vuetify v-combobox для одного выбора - PullRequest
0 голосов
/ 10 октября 2019

В большом приложении Vue, использующем Vuetify, у меня есть следующий многократно используемый компонент, используемый во всем приложении:

<template>
  <v-combobox
    v-model="input"
    :items="available"
    :item-value="itemValue"
    :item-text="itemText"
    :label="label"
    :disabled="disabled"
    :hint="hint"
    chips
    multiple
    persistent-hint
    @input="myInput"
  >
    <template slot="selection" slot-scope="data">
      <v-chip
        :close="!disabled"
        @input="remove(data.item)"
      >
        <strong>{{ data.item.code }}</strong>
      </v-chip>
    </template>
  </v-combobox>
</template>

<script>
export default {
  name: 'BaseSelectChip',
  props: {
    hint: String,
    value: Array,
    label: String,
    available: Array,
    disabled: Boolean,
    itemText: {
      type: String,
      required: true,
    },
    itemValue: {
      type: String,
      required: true,
    },
  },
  computed: {
    input: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      },
    },
  },
  methods: {
    myInput(items) {
      this.input = [...this.items];
      this.$emit('input', items);
    },
    remove(item) {
      const newItems = this.input.slice();
      newItems.splice(this.input.indexOf(item), 1);
      this.$emit('input', newItems);
    },
  },
};
</script>

, и он обычно используется так:

<BaseSelectChip
  label="Liveness Options"
  :value="tenantBiometricLiveness"
  :available="getAvailableLiveness"
  :disabled="!hasBiometric"
  itemValue="code"
  itemText="name"
  :hint="livenessHint"
  @input="livenessUpdated"
/>

К этому моменту все реализации в моем приложении допускают множественный выбор, но у меня есть случай, когда я хочу ограничить его одним выбором. Согласно документам , это логическое значение, но также говорит, что этот реквизит Accepts array for value. Кроме того, в нем указывается, что значением по умолчанию является false, но когда оно передается само по себе v-combobox, оно позволяет выбрать несколько параметров. Если я определю реквизит в BaseSelectChip следующим образом:

props: {
  multiple: {
    type: Boolean,
    default: true,
  },
}

, а затем передам его v-combobox

  <v-combobox
    v-model="input"
    :items="available"
    :item-value="itemValue"
    :item-text="itemText"
    :label="label"
    :disabled="disabled"
    :hint="hint"
    chips
    :multiple="multiple"
    persistent-hint
    @input="myInput"
  >

независимо от того, как я передам его от родительского компонента, мойэкран просто пустой, и я не получаю предупреждений консоли, что говорит мне, что Veutify где-то тихо умирает.

Когда я удаляю multiple из элемента v-combobox, я получаю пустой элемент в своем поле, дажехотя в поле нет элемента (items prop): blank chip in v-combobox

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

Итак, у меня следующие вопросы: 1) Как передать значение для multiple подпишите до <BaseSelectChip> (а затем и до v-combobox), сколько необходимо для v-combobox? 2) Как я могу настроить в выпадающем списке только один элемент, который может быть выбран одновременно, и показывать фишку только тогда, когда элемент фактически выбран?

ОБНОВЛЕНИЕ: Таким образом, для реализации @ skirtle'sПредложение ниже: я изменил BaseSelectChip примерно так:

  <v-combobox
    v-model="input"
    :items="available"
    :item-value="itemValue"
    :item-text="itemText"
    :label="label"
    :disabled="disabled"
    chips
    :multiple="multiple"
    @input="myInput"
  >

...

props: {
  multiple: {
      type: Boolean,
      required: false,
      default: true,
    },
  },

, а затем добавил :multiple="false" в родительский компонент. Кажется, это работает нормально, но теперь есть один побочный эффект: в BaseSelectChip значение, которое выводится из myInput (исходя из события @input в выпадающем списке), составляет Observer вместо Array,Это вызывает проблемы в родительском компоненте, потому что он ищет массив. Почему он использует Обозреватель?

1 Ответ

0 голосов
/ 10 октября 2019

Любой реквизит с type, равным Boolean, может быть написан с использованием сокращения для передачи true. Поэтому, когда вы пишете:

<v-combobox multiple>

Это просто сокращение для:

<v-combobox :multiple="true">

Это не относится к Vuetify, это общее поведение Vue и применяется ко всем компонентам.

В вашем случае вы установили значение по умолчанию true, поэтому вам нужно будет явно передать false:

<BaseSelectChip
  :multiple="false"
>

Будьте осторожны, чтобы включить : спереди илиВместо этого я передам строку 'false', которая очень отличается.

Вы упомянули запись в документах, в которой говорится:

Принимает массив для значения

Это означает, что если вы установите multiple на true, то value prop v-combobox должен быть массивом. В вашем коде вы не устанавливаете опору value напрямую, а устанавливаете ее с помощью v-model.

Если multiple установлен на false, то value не будет ожидать массив,Поскольку вы используете v-model, это повлияет на вас в обоих направлениях. У вас есть несколько строк, которые, по-видимому, предполагают, что значение будет массивом, поэтому их нужно будет изменить.

Возможно, именно поэтому вы видите один пустой чип. Я предполагаю, что вы передаете пустой массив. Но с multiple, установленным на false, он будет обрабатывать этот массив как выбранное значение. В этом случае нет специальной обработки массивов, это просто значение, как и любое другое. Он будет искать [].code и [].name для item-value и item-text, которые будут undefined.

...