Solución:
El enlace bidireccional ha quedado obsoleto en Vue 2.0 a favor de utilizar una arquitectura más impulsada por eventos. En general, un niño no debe mutar sus accesorios. Más bien, debería $emit
eventos y dejar que los padres respondan a esos eventos.
En su caso específico, puede utilizar un componente personalizado con v-model
. Esta es una sintaxis especial que permite algo parecido al enlace bidireccional, pero en realidad es una forma abreviada de la arquitectura impulsada por eventos descrita anteriormente. Puede leer sobre esto aquí -> https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events.
He aquí un ejemplo sencillo:
Vue.component('child', {
template: '#child',
//The child has a prop named 'value'. v-model will automatically bind to this prop
props: ['value'],
methods: {
updateValue: function (value) {
this.$emit('input', value);
}
}
});
new Vue({
el: '#app',
data: {
parentValue: 'hello'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<p>Parent value: {{parentValue}}</p>
<child v-model="parentValue"></child>
</div>
<template id="child">
<input type="text" v-bind:value="value" v-on:input="updateValue($event.target.value)">
</template>
Los documentos afirman que
<custom-input v-bind:value="something" v-on:input="something = arguments[0]"></custom-input>
es equivalente a
<custom-input v-model="something"></custom-input>
Es por eso que el accesorio en el niño necesita ser nombrado valor, y por qué el niño necesita $ emitir un evento llamado input
.
De la documentación:
En Vue.js, la relación del componente padre-hijo se puede resumir como apoyos hacia abajo, eventos hacia arriba. El padre pasa datos al niño a través de accesorios y el niño envía mensajes al padre a través de eventos. Veamos cómo funcionan a continuación.
Cómo pasar accesorios
A continuación se muestra el código para pasar accesorios a un elemento secundario:
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
Cómo emitir evento
HTML:
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
JS:
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
increment: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
En componente hijo:
this.$emit('eventname', this.variable)
En componente padre:
<component @eventname="updateparent"></component>
methods: {
updateparent(variable) {
this.parentvariable = variable
}
}