vue.js - two - Unión bidireccional en el componente Vue 2.3
two data binding vue (1)
Tu construcción tiene algunas rarezas que no funcionaron, pero básicamente answer.sync
funciona si lo propagas al componente q-radio
donde ocurre el cambio. Cambiar la respuesta en el elemento primario se maneja correctamente, pero para borrar los valores, parece que debe establecerlo en un objeto en lugar de nulo (creo que esto se debe a que debe ser asignable).
Actualizar Tu configuración de options
es algo notable que no funcionó.
Utilizo la answer
en el q-radio
para controlar su estado verificado ( v-model
tiene un comportamiento especial en una radio, por lo que utilizo el value
junto con v-model
). De su comentario, parece que q-radio
quiere tener un valor que pueda establecer. Debería poder hacer eso con un cálculo basado en la answer
, que usaría en lugar de su elemento de datos de opción: la answer
devoluciones, y el set
emit
. He actualizado mi fragmento para usar el val
prop para q-radio
más el cálculo que describo. El proxyAnswer
emite un evento de update
, que es lo que quiere el modificador .sync
. También implementé q-radio
usando un proxy calculado, pero eso es solo para obtener el comportamiento que ya debería estar cocido, en su q-radio
.
(Lo que describo es efectivamente lo que estás haciendo con un elemento de datos y un observador, pero un cálculo es una forma más agradable de encapsular eso).
new Vue({
el: ''#app'',
data: {
userChoice: null,
options: [''Blue'', ''No, wait, aaaaargh!''].map(v => ({
value: v,
text: v
}))
},
components: {
question: {
props: {
stem: String,
options: Array,
answer: String
},
computed: {
proxyAnswer: {
get() {
return this.answer;
},
set(newValue) {
this.$emit(''update:answer'', newValue);
}
}
},
components: {
qRadio: {
props: [''value'', ''val''],
computed: {
proxyValue: {
get() {
return this.value;
},
set(newValue) {
this.$emit(''input'', newValue);
}
}
}
}
}
}
},
methods: {
clearSelection() {
this.userChoice = {};
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
<question stem="What is your favourite colour?" :options="options" :answer.sync="userChoice" inline-template>
<div>
<h5>{{stem}}</h5>
<div class="option" v-for="opt in options">
<div>Answer={{answer && answer.text}}, option={{opt.text}}</div>
<label>
<q-radio :val="opt" v-model="proxyAnswer" inline-template>
<input type="radio" :value="val" v-model="proxyValue">
</q-radio>
{{opt.text}}
</label>
</div>
</div>
</question>
<button @click="clearSelection">Clear</button>
</div>
Comprendo el modificador .sync
devuelto en Vue 2.3, y lo estoy usando para un componente secundario simple que implementa una pregunta y respuesta de ''opción múltiple''. El componente principal llama al niño así:
<question
:stem="What is your favourite colour?"
:options="[''Blue'', ''No, wait, aaaaargh!'']
:answer.sync="userChoice"
>
El padre tiene un elemento de datos de cadena userChoice
para almacenar el resultado del componente secundario. El niño presenta la pregunta y los botones de radio para las opciones. Los bits esenciales del niño se ven así (estoy usando Quasar, de ahí q-radio
):
<template>
<div>
<h5>{{stem}}</h5>
<div class="option" v-for="opt in options">
<label >
<q-radio v-model="option" :val="opt.val" @input="handleInput"></q-radio>
{{opt.text}}
</label>
</div>
</div>
</template>
export default {
props: {
stem: String,
options: Array,
answer: String
},
data: () => ({
option: null
}),
methods: {
handleInput () {
this.$emit(''update:answer'', this.option)
}
}
}
Todo está funcionando bien, aparte del hecho de que si el padre cambia el valor de userChoice
debido a que sucede algo más en la aplicación, el niño no actualiza los botones de radio. Tuve que incluir este watch
en el niño:
watch: {
answer () {
this.option = this.answer
}
}
Pero se siente un poco redundante, y me preocupaba que emitir el evento para actualizar los datos de los padres de hecho causaría que el evento de "vigilancia" infantil también se active. En este caso, no tendría ningún otro efecto que desperdiciar unos pocos ciclos, pero si estuviera registrando o contando algo, sería un falso positivo ...
Tal vez esa sea la solución correcta para la vinculación verdadera de dos vías (es decir, dinámica → secundaria → secundaria, → secundaria → secundaria). ¿Perdí algo acerca de cómo conectar los datos de "entrada" y "salida" en ambos lados?
En caso de que se lo pregunte, el caso más común del padre que desea cambiar ''userChoice'' sería en respuesta a un botón ''Clear Answers'' que establecería userChoice
en una cadena vacía. Eso debería tener el efecto de ''desarmar'' todos los botones de radio.