O princípio da vinculação de eventos no Vue

Quando pesquisei esse princípio antes, só escrevi duas frases em muitos artigos:

A associação de eventos nativos é vinculada a elementos reais por meio de addEventListener.
A vinculação de evento de componente é obtida por meio da chave personalizada $ on do Vue.

Como isso aconteceu? Não disse?
Vamos dar uma olhada nisso agora.

// 原生事件绑定
<div @click="fn()"></div>

// 组件绑定
<my-component @click.native="fn" @click="fn1"></my- component>

Princípio:
Compilação de eventos:

let compiler = require('vue-template-compiler'); //vue-loader
let r1 = compiler.compile('<div @click="fn()"></div>'); 
let r2 = compiler.compile('<my-component @click.native="fn" @click="fn1"></my- component>'); console.log(r1); 
// {on:{click}} console.log(r2); 
// {nativeOn:{click},on:{click}}

Os dois compilados não são iguais

// 前者
with (this){
    
    return _c('div',{
    
    on:{
    
    "click":function($event){
    
    return fn()}}})}

// 后者
with (this){
    
    return _c('my-component',{
    
    on:{
    
    "click":fn1},nativeOn:{
    
    "click":function($event){
    
    return fn($event)}}})}

Insira a descrição da imagem aqui

1.1 Vinculação de dom nativo

  • O Vue chamará createElm ao criar um dom real e invokeCreateHooks será chamado por padrão
  • Percorrerá o código de processamento de atributo relativo na plataforma atual, incluindo o método updateDOMListeners, e o método add será passado internamente

Código fonte:

function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) {
    
     
	if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
    
     return }
	const on = vnode.data.on || {
    
    } const oldOn = oldVnode.data.on || {
    
    } 
	target = vnode.elm 
	normalizeEvents(on) 
	updateListeners(on, oldOn, add, remove, createOnceHandler, vnode.context) 
	target = undefined 
}
function add ( 
	name: string, 
	handler: Function, 
	capture: boolean, 
	passive: boolean 
) {
    
    
	target.addEventListener( // 给当前的dom添加事件 
		name, 
		handler, 
		supportsPassive 
		? {
    
      capture, passive  } 
		: capture 
	) 
}

1.2 Eventos de ligação em componentes

export function updateComponentListeners ( 
	vm: Component, 
	listeners: Object, 
	oldListeners: ?Object 
) {
    
    
	target = vm updateListeners(
		listeners, oldListeners || {
    
    }, 
		add, 
		remove,
		createOnceHandler, vm)
		target = undefined 
}

function add (event, fn) {
    
     
	target.$on(event, fn) 
}

Os eventos de ligação de componentes são implementados por meio do método $ on customizado em vue

1.3 Como $ on funciona?

vm.$on( event, callback )

efeito:

Ouça eventos personalizados na instância atual. O evento pode ser acionado por vm. $ Emit. A função de retorno de chamada receberá todos os parâmetros extras da função de gatilho de evento de entrada.

princípio:

$ on adota o padrão clássico de design publicar-assinante. Primeiro, defina um centro de eventos, inscreva-se em eventos por meio de $ on, armazene os eventos no centro de eventos e, a seguir, acione os eventos de inscrição armazenados no centro de eventos por meio de $ emit.

Vue.prototype.$on = function (event, fn) {
    
    
    const vm: Component = this
    if (Array.isArray(event)) {
    
    
        for (let i = 0, l = event.length; i < l; i++) {
    
    
            this.$on(event[i], fn)
        }
    } else {
    
    
        (vm._events[event] || (vm._events[event] = [])).push(fn)
    }
    return vm
}

Olhando para o código, a lógica é muito simples. A função $ on recebe dois parâmetros. O primeiro é o nome do evento inscrito, que pode ser múltiplo. Se houver vários, uma matriz de nomes de eventos é passada. A outra é a função de retorno de chamada. Primeiro, determine se o evento de entrada é um array. Se for, atravesse o array e chame recursivamente o método $ on para cada evento no array para inscrevê-lo como um único evento. Se não for um array, trate-o como um único nome de evento, use o nome do evento como a chave, primeiro tente obter a lista de eventos correspondente na propriedade _events da instância atual, se não estiver disponível, dê-lhe um vazio array como o valor padrão e adicione a segunda função de retorno de chamada de parâmetro.

Mais uma frase, quais são os _events da instância? Quando o evento é inicializado, o atributo _event é vinculado à função initEvents e atribuído a um objeto vazio. Este atributo _events é usado como o centro de eventos da instância atual e todos os eventos vinculados a esta instância serão armazenados no atributo _events do centro de eventos.

Este é o princípio interno de $ on.

Acho que você gosta

Origin blog.csdn.net/Beth__hui/article/details/114089801
Recomendado
Clasificación