El patrón Vue es propshacia abajo y hacia eventsarriba. Suena simple, pero es fácil de olvidar al escribir un componente personalizado.
A partir de Vue 2.2.0, puede usar v-model (con propiedades calculadas ). He descubierto que esta combinación crea una interfaz simple, limpia y consistente entre componentes:
- Todo lo que se
propspasa a su componente permanece reactivo (es decir, no está clonado ni requiere una watchfunción para actualizar una copia local cuando se detectan cambios).
- Los cambios se emiten automáticamente a los padres.
- Se puede usar con múltiples niveles de componentes.
Una propiedad calculada permite que el definidor y el captador se definan por separado. Esto permite que el Taskcomponente se reescriba de la siguiente manera:
Vue.component('Task', {
template: '#task-template',
props: ['list'],
model: {
prop: 'list',
event: 'listchange'
},
computed: {
listLocal: {
get: function() {
return this.list
},
set: function(value) {
this.$emit('listchange', value)
}
}
}
})
La propiedad del modelo define qué propestá asociado v-modely qué evento se emitirá en los cambios. Luego puede llamar a este componente desde el padre de la siguiente manera:
<Task v-model="parentList"></Task>
La listLocalpropiedad calculada proporciona una interfaz getter y setter simple dentro del componente (piense que es una variable privada). Dentro de #task-templateusted puede renderizar listLocaly permanecerá reactivo (es decir, si parentListcambia, actualizará el Taskcomponente). También puede mutar listLocalllamando al configurador (por ejemplo, this.listLocal = newList) y emitirá el cambio al padre.
Lo bueno de este patrón es que puede pasar listLocala un componente secundario de Task(usar v-model), y los cambios del componente secundario se propagarán al componente de nivel superior.
Por ejemplo, supongamos que tenemos un EditTaskcomponente separado para realizar algún tipo de modificación en los datos de la tarea. Al usar el mismo v-modelpatrón de propiedades calculadas podemos pasar listLocalal componente (usando v-model):
<script type="text/x-template" id="task-template">
<div>
<EditTask v-model="listLocal"></EditTask>
</div>
</script>
Si EditTaskemite un cambio llamará apropiadamente set()en listLocaly por lo tanto propagar el evento para el nivel superior. Del mismo modo, el EditTaskcomponente también podría llamar a otros componentes secundarios (como elementos de formulario) usando v-model.