Vue компонент V-модель с обработчиком ввода - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь создать компонент-оболочку для элемента <input/> в Vue.js.

Компонент:

<template>
  <div>
    <input v-bind="$attrs" :value="value" @input="input" />
    ...
  </div>
<template>

Vue.component("my-input", {
   inheritAttrs: false,
   props: ['value'],
   methods: {
     input($event): void {
       this.$emit("input", $event.target.value)
     }
  }
})

Использование:

<my-input v-model="myModel" />

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

Однако сейчас я пытаюсь использовать этот компонент с некоторым существующим кодом:

<my-input v-model="myModel2" @input="something = $event.target.value" />

Это гдеУ меня проблемы с событием $emit("input").Я получаю следующую ошибку:

Невозможно прочитать свойство 'значение' из неопределенного

Итак, мой $emit испускает значение и теперь существующий обработчик событий @input="something..." не может правильно ссылаться на $event.

Если я изменю метод input моего компонента, чтобы он выдавал $event вместо $event.target.value, новый код кажетсяна работу, но тогда модель не обновляется обновляется до InputEvent вместо фактического значения .

Я неуверен, что мне нужно сделать.

Ответы [ 3 ]

1 голос
/ 09 июля 2019

Когда вы $emit('input') и значение привязано к v-model текстового ввода, значение <input> будет обновлено до того, что вы испустили. В случае $emit('input', $event.target.value) это значение текста в <input>, которое вы излучаете. Это значение будет перехвачено в родительском элементе, как это делает v-model: <my-input :value="inputValue" @input="inputValue = $event">

Это означает, что значение <input> будет привязано к <input> (что фактически не приводит к изменению значения на входе). Однако, если вы $emit('input', $event), то v-model по-прежнему будет захватывать любое переданное значение и обновлять значение <input> вместе с ним. В этом случае, как вы сказали, это будет фактический объект входного события.

Если вы не хотите использовать событие input, связанное с вашей моделью, вы всегда можете использовать пользовательское v-model событие . Тогда вы сможете $emit('input', $event), и это не повлияет на значение v-модели, вместо этого вы обновите v-модель с $emit('custom-event', $event.target.value)

1 голос
/ 09 июля 2019

Просто присвойте их родителям напрямую вместо создания прокси

const MyInput = Vue.extend({
  name: 'MyInput',
  template: '#ins',
  data(){return{valid: true}},
  methods: {validate(ev){this.valid = ev.target.value.length < 1 ;this.$listeners.input(ev)}}
})

const App = Vue.extend({
  components: {
    MyInput
  },
  template: '#myinput',
  data(){return{val: 'test'}},
  methods: {ins(ev){console.log(ev.target.value)}}
})

new Vue({
  name: 'root',
  render: h => h(App)
}).$mount("#app");
input {background: red}
.valid{background:green !important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app"></div>

<template id="ins">
  <input v-bind="$attrs" @input="validate" :class="{valid:valid}"/>
</template>

<template id="myinput">
    <my-input v-model="val" @input="ins" />
</template>
1 голос
/ 09 июля 2019

Попробуйте

<my-input v-model="myModel2" @input="value => something = value" />
...