O padrão Vue está props
baixo e events
ativo. 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
props
passagem para seu componente permanece reativa (ou seja, não é clonada nem requer uma watch
funçã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 Task
componente 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 prop
está associado v-model
e qual evento será emitido nas alterações. Você pode chamar esse componente do pai da seguinte maneira:
<Task v-model="parentList"></Task>
A listLocal
propriedade computada fornece uma interface simples de getter e setter dentro do componente (pense nisso como uma variável privada). Dentro de #task-template
você pode renderizar listLocal
e permanecerá reativo (ou seja, se houver parentList
alterações, ele atualizará o Task
componente). Você também pode fazer uma mutação listLocal
chamando 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 listLocal
para 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 EditTask
componente separado para fazer algum tipo de modificação nos dados da tarefa. Usando o mesmo v-model
padrão de propriedades e computado, podemos passar listLocal
para o componente (using v-model
):
<script type="text/x-template" id="task-template">
<div>
<EditTask v-model="listLocal"></EditTask>
</div>
</script>
Se EditTask
emite um mudança que vai chamar apropriadamente set()
em listLocal
e, assim, propagar o evento para o nível superior. Da mesma forma, o EditTask
componente também pode chamar outros componentes filhos (como elementos de formulário) usando v-model
.