Prefácio: No trabalho real, existem muitos cenários em que os dados são processados em componentes filhos e as alterações de dados precisam ser obtidas de forma síncrona nos componentes pais. Por exemplo, uma página de consulta tem muitas condições de consulta. Suponha que haja um subcomponente que seleciona componentes para regiões. Precisamos realizar a operação de consulta imediatamente após selecionar a região. Neste momento, precisamos sincronizar os dados entre o pai e componentes filhos.
1. Definição e introdução de subcomponentes
Existem duas maneiras de definir subcomponentes: registro global e registro local. No entanto, no meu trabalho real, basicamente uso o registro local para definir o subcomponente como um arquivo. O componente pai introduz o subcomponente e registra o subcomponente .vue
em import
: components
componente
pai
import AreasSelector from '@/components/AreasSelector/index';
...
components: {
AreasSelector
},
Ao usar um subcomponente em um componente pai, você deve projetar quais parâmetros o subcomponente pode aceitar e quais parâmetros ele deve retornar, com base nos respectivos cenários de negócios.
Aqui meu componente filho pode receber dois parâmetros passados do componente pai: um é a areaIds
região que foi selecionada no componente pai ids
; o outro é isMulti
se a região suporta múltiplas seleções. Você precisa usá-lo ao passar dados de um componente pai para um componente filho props
. Se você estiver passando dados estáticos (strings, números, etc.), não será necessário adicioná-los :
. Se quiser passar dados dinâmicos (dados que precisa ser obtido da instância do componente atual), você precisa adicioná-lo :
.
Os parâmetros a serem retornados pelo subcomponente são aqueles selecionados após o usuário clicar no comportamento areaIds
. $on
Para receber os parâmetros retornados pelo subcomponente, é necessário definir uma função de callback onde o subcomponente é utilizado, que equivale a um observador:
no componente pai
<AreasSelector :props="{areaIds,isMulti:true}" @area-change="onAreaChange"></AreasSelector>
Onde os dados precisarem ser enviados em um subcomponente, use $emit
Enviar Dados, que equivale a um editor:
no subcomponente
this.$emit('area-change', newVal);
$on
E $emit
o modo observador é usado, ou seja, $emit
você precisa encontrar todas as $on
funções de retorno de chamada definidas e, em seguida, executar todas as funções de retorno de chamada. Você pode simplesmente dar uma olhada no vue
código-fonte. Eu mantive apenas as partes mais críticas:
Vue.prototype.$emit = function (event) {
var vm = this;
// cbs中存储着$on定义的回调函数列表
var cbs = vm._events[event];
if (cbs) {
cbs = cbs.length > 1 ? toArray(cbs) : cbs;
var args = toArray(arguments, 1);
var info = "event handler for \"" + event + "\"";
for (var i = 0, l = cbs.length; i < l; i++) {
// 到这个函数中执行回调函数
invokeWithErrorHandling(cbs[i], vm, args, vm, info);
}
}
return vm
};
Em segundo lugar, observe
Dentro do componente filho, quando o usuário clica em uma região, uma série de processamentos é necessária, e o processamento é convertido em uma id
matriz de regiões e passado para o componente pai. Podemos chamar manualmente o processo de passá-lo para o componente pai $emit
ou podemos deixá-lo watch
monitorar as alterações de dados e watch
chamá-lo internamente $emit
.
O documento oficial de observação
watch
é vue
um objeto de atributo que pode ser definido pelo componente. data
Ele é usado para monitorar vue
alterações nos dados do componente. Existem três formas de definição key
para os dados que precisam ser monitorados : ① O nome do método da função de retorno de chamada , uma string ② Objeto, em que O atributo é um método de função de retorno de chamada. Quando o atributo é , significa que a função de retorno de chamada também será acionada quando os atributos profundos do objeto de destino monitorado mudarem; quando o atributo for definido como , ele será chamado imediatamente após o início da escuta ③ Matriz de função de retorno de chamada, eles serão executados em sequência Podemos definir um para os dados que precisam ser passados para o componente pai , monitorar suas alterações em tempo real e chamar automaticamente :value
handler
deep
true
immediate
true
watcher
$emit
watch: {
'areaData': {
handler(newVal, oldVal) {
if (!newVal) return;
this.$emit('area-change', newVal);
},
deep: true,
immediate: true
}
},