Как я могу использовать v-модель с функциональным компонентом шаблона в Vue? - PullRequest
1 голос
/ 25 марта 2019

Vue.js содержит пример , демонстрирующий, как создать функциональный компонент, обертывающий кнопку:

<template functional>
  <button
    class="btn btn-primary"
    v-bind="data.attrs"
    v-on="listeners"
  >
    <slot/>
  </button>
</template>

Но как я могу создать аналогичный компонент, работающийс select, который я могу затем использовать v-model на его родителе?

Я придумал следующее, но когда я использую v-model на нем, вот так:

<MyComponent :Label="'Status'" :Data="Statuses" v-model="selectedStatus" />

Значение selectedStatus становится:

[object Event]
<template functional>
    <select v-bind:value="data.attrs" v-on="listeners">
        <option>-</option>
        <option v-for="item in props.Data" :key="item" :value="item">{{item}}</option>
    </select>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";

@Component
export default class TaskSelector extends Vue {
  @Prop({ type: String, required: true })
  public Label!: string;

  @Prop({ type: Array, required: true })
  public Data!: string[];
}
</script>

1 Ответ

2 голосов
/ 26 марта 2019

Для правильной работы v-model компонент должен получить реквизит value и выдать событие input, данные которого представляют собой значение string . Но родные данные *1009*input - это объект InputEvent, преобразованный в строку ([object Event]), который дает неверный результат с ограничением v-model.

Чтобы исправить это, нам нужно изменить данные события <select> input до того, как они достигнут родителя. Это требует удаления <select v-on="listeners">, что позволило бы проблемному нативному событию input распространиться на родителя. Затем мы используем listeners.input($event.target.selectedOptions[0].value) для пересылки события input со строковым значением выбранного параметра.

Шаги:

  1. Добавьте value реквизит и привяжите <select> :value к value рек.
  2. Переиздать событие <select> input со значением выбранного параметра. Это должно заменить v-on="listeners".

Ваш SFC должен выглядеть так:

<template functional>
  <select
    1️⃣:value="props.value"
    2️⃣@input="listeners.input && listeners.input($event.target.selectedOptions[0].value)"
  >
    <option value="">-</option>
    <option v-for="item in props.Data" :key="item" :value="item">{{item}}</option>
  </select>
</template>

демо

...