O padrão Vue está propsbaixo e eventsativo. Parece simples, mas é fácil esquecer ao escrever um componente personalizado.
A partir do Vue 2.2.0, você pode usar o modelo v (com propriedades calculadas ). Eu descobri que essa combinação cria uma interface simples, limpa e consistente entre os componentes:
- Qualquer
propspassagem para seu componente permanece reativa (ou seja, não é clonada nem requer uma watchfunção para atualizar uma cópia local quando são detectadas alterações).
- As alterações são emitidas automaticamente para o pai.
- Pode ser usado com vários níveis de componentes.
Uma propriedade computada permite que o setter e o getter sejam definidos separadamente. Isso permite que o Taskcomponente seja reescrito da seguinte maneira:
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)
}
}
}
})
A propriedade model define a qual propestá associado v-modele qual evento será emitido nas alterações. Você pode chamar esse componente do pai da seguinte maneira:
<Task v-model="parentList"></Task>
A listLocalpropriedade computada fornece uma interface simples de getter e setter dentro do componente (pense nisso como uma variável privada). Dentro de #task-templatevocê pode renderizar listLocale permanecerá reativo (ou seja, se houver parentListalterações, ele atualizará o Taskcomponente). Você também pode fazer uma mutação listLocalchamando o setter (por exemplo, this.listLocal = newList) e ele emitirá a alteração para o pai.
O melhor desse padrão é que você pode passar listLocalpara um componente filho de Task(using v-model), e as alterações do componente filho serão propagadas para o componente de nível superior.
Por exemplo, digamos que temos um EditTaskcomponente separado para fazer algum tipo de modificação nos dados da tarefa. Usando o mesmo v-modelpadrão de propriedades e computado, podemos passar listLocalpara o componente (using v-model):
<script type="text/x-template" id="task-template">
<div>
<EditTask v-model="listLocal"></EditTask>
</div>
</script>
Se EditTaskemite um mudança que vai chamar apropriadamente set()em listLocale, assim, propagar o evento para o nível superior. Da mesma forma, o EditTaskcomponente também pode chamar outros componentes filhos (como elementos de formulário) usando v-model.