Il modello Vue è props
su 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
props
passaggio al componente rimane reattivo (ovvero non viene clonato né richiede una watch
funzione 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 Task
di 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-model
e quale evento verrà emesso sulle modifiche. È quindi possibile chiamare questo componente dal genitore come segue:
<Task v-model="parentList"></Task>
La listLocal
proprietà 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 listLocal
e questo rimarrà reattivo (ovvero, se viene parentList
modificato, aggiornerà il Task
componente). Puoi anche mutare listLocal
chiamando il setter (ad esempio, this.listLocal = newList
) ed emetterà la modifica al genitore.
La cosa grandiosa di questo modello è che puoi passare listLocal
a 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 EditTask
componente separato per apportare qualche tipo di modifica ai dati dell'attività. Usando lo stesso v-model
modello di proprietà calcolato e possiamo passare listLocal
al componente (usando v-model
):
<script type="text/x-template" id="task-template">
<div>
<EditTask v-model="listLocal"></EditTask>
</div>
</script>
Se EditTask
emette una modifica, verrà richiamato set()
in listLocal
modo appropriato e quindi propagherà l'evento al livello superiore. Allo stesso modo, il EditTask
componente potrebbe anche chiamare altri componenti figlio (come gli elementi del modulo) utilizzando v-model
.