Как заставить компонент Vue работать с типом значения, сохраняющим v-модель? - PullRequest
0 голосов
/ 26 июня 2018

Задача

Когда у меня есть v-model в HTML <select>, v-model устанавливает заданное свойство для выбранных значений, сохраняя типы этих значений - если я связываю число с <option>, свойство модели устанавливается нумерации, если я связываю объект, он устанавливается на этот объект.

<script>
export default {
  data: {
    options: [5, 10, 15, 'text', { 'description': 'I am an Object' }],
  }
};
</script>

<template>
  <select v-model="model">
    <option
      v-for="option in options"
      :value="option"
    >
      {{ option }}
    </option>
  </select>
<template>

У меня есть пользовательский компонент <base-select>, который оборачивается для меня использованием тега <select>. Я пытаюсь реализовать то же самое поведение v-model для него, но не могу, потому что типы не сохраняются - мне возвращаются строки все время, даже когда я связываю числа или объекты.

//// BaseSelect.vue

<script>
export default {
  props: {
    options: {
      type: Array,
      required: true
    },
    value: {
      required: true
    }
  },
};
</script>
<template>
  <select
    :value="value"
    @input="$emit('input', $event.target.value)"
  >
    <option
      v-for="option in options"
      :value="option"
    >
      {{ option }}
    </option>
  </select>
</template>

//// App.vue

<script>
  @import 'BaseSelect' from './BaseSelect';

  export default {
    components: {
      BaseSelect,
    },
    data: {
      options: [5, 10, 15, 'text', { 'description': 'I am an Object' }],
    }
  };
</script>
<template>
  <base-select
    v-model="model"
    :options="options"
  />
<template>

Fiddle

Вот где это поведение хорошо видно: http://jsfiddle.net/4o67pzLs/14/

Первый выбор - сохранение типов значений, привязанных к модели, в то время как второй выбор - все значения времени, устанавливаемые в строки.

Вопрос * * 1023 Можно ли реализовать v-model на пользовательском компоненте, который бы сохранял типы? Если да, то как?

1 Ответ

0 голосов
/ 26 июня 2018

Вот как мы наконец сделали это вместе с @RobertKusznier:

  • Свяжите выбор с вычисленным свойством компонента, используя v-model
  • Определите для него метод получения и установкивычисляемое свойство
  • Получатель возвращает значение компонента
  • Установщик генерирует событие изменения

Сохраняет тип значения выбранного параметра и неизменить значение компонента.

Кредит переходит к @RobertKusznier, который предположил, что мы не изменили значение компонента.

let baseSelect = {
	props: {
  	options: {
    	type: Array,
      required: true
    },
    value: {
    	required: true
    }
  },
  
  computed: {
  	valueCopy: {
    	get() {
      	return this.value;
      },
      set(value) {
      	this.$emit('input', value);
      }
    }
  },
  
  template: `
  	<select
      v-model="valueCopy"
    >
      <option
        v-for="option in options"
        :value="option"
      >
        {{ option }}
      </option>
    </select>
  `,
};

new Vue({
	el: '#app',
  components: {
  	baseSelect
  },
  data: {
  	model: 5,
    options: [5, 10, 15, 'text', new Date()]
  },
  template: `
    <div>
      <select v-model="model">
        <option
          v-for="option in options"
          :value="option">
            {{ option }}
        </option>
      </select>
      
      <base-select
        v-model="model"
        :options="options"
        :sister="10"
      />
      
      <p>model: {{ model }}</p>
      <p>typeof model: {{ typeof model }}</p>
    </div>
  `
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app"></div>
...