Il modello Vue è propssu e giù events. Sembra semplice, ma è facile dimenticare quando si scrive un componente personalizzato.
A partire da Vue 2.2.0 è possibile utilizzare v-model (con proprietà calcolate ). Ho scoperto che questa combinazione crea un'interfaccia semplice, pulita e coerente tra i componenti:
- Qualsiasi
propspassaggio al componente rimane reattivo (ovvero non viene clonato né richiede una watchfunzione per aggiornare una copia locale quando vengono rilevate modifiche).
- Le modifiche vengono automaticamente emesse al genitore.
- Può essere utilizzato con più livelli di componenti.
Una proprietà calcolata consente di definire separatamente setter e getter. Ciò consente Taskdi riscrivere il componente come segue:
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 proprietà del modello definisce a quale propè associato v-modele quale evento verrà emesso sulle modifiche. È quindi possibile chiamare questo componente dal genitore come segue:
<Task v-model="parentList"></Task>
La listLocalproprietà calcolata fornisce una semplice interfaccia getter e setter all'interno del componente (pensala come una variabile privata). All'interno #task-templateè possibile eseguire il rendering listLocale questo rimarrà reattivo (ovvero, se viene parentListmodificato, aggiornerà il Taskcomponente). Puoi anche mutare listLocalchiamando il setter (ad esempio, this.listLocal = newList) ed emetterà la modifica al genitore.
La cosa grandiosa di questo modello è che puoi passare listLocala un componente figlio di Task(usando v-model), e le modifiche dal componente figlio si propagheranno al componente di livello superiore.
Ad esempio, supponiamo di avere un EditTaskcomponente separato per apportare qualche tipo di modifica ai dati dell'attività. Usando lo stesso v-modelmodello di proprietà calcolato e possiamo passare listLocalal componente (usando v-model):
<script type="text/x-template" id="task-template">
<div>
<EditTask v-model="listLocal"></EditTask>
</div>
</script>
Se EditTaskemette una modifica, verrà richiamato set()in listLocalmodo appropriato e quindi propagherà l'evento al livello superiore. Allo stesso modo, il EditTaskcomponente potrebbe anche chiamare altri componenti figlio (come gli elementi del modulo) utilizzando v-model.