El principio de vinculación de eventos en Vue

Cuando busqué este principio antes, solo escribí dos oraciones en muchos artículos:

El enlace de eventos nativo está vinculado a elementos reales a través de addEventListener.
La vinculación de eventos de componentes se logra a través de la clave personalizada $ on de Vue.

¿Cómo sucedió eso? ¿No lo dijiste?
Echemos un vistazo ahora.

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

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

Principio:
Recopilación 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}}

Los dos compilados no son iguales

// 前者
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)}}})}

Inserte la descripción de la imagen aquí

1.1 Vinculación de dom nativo

  • Vue llamará a createElm al crear un dom real, y se llamará invokeCreateHooks de forma predeterminada
  • Atravesará el código de procesamiento de atributos relativos en la plataforma actual, incluido el método updateDOMListeners, y el método add se pasará internamente

Código fuente:

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 Vinculación de eventos en 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) 
}

Los eventos de enlace de componentes se implementan a través del método $ on personalizado en vue

1.3 ¿Cómo funciona $ on?

vm.$on( event, callback )

efecto:

Escuche eventos personalizados en la instancia actual. El evento puede ser desencadenado por vm. $ Emit. La función de devolución de llamada recibirá todos los parámetros adicionales de la función de activación del evento entrante.

principio:

$ on adopta el patrón clásico de diseño publicar-suscriptor. Primero, defina un centro de eventos, suscríbase a eventos a través de $ on, almacene los eventos en el centro de eventos y luego active los eventos de suscripción almacenados en el centro de eventos a través 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
}

Al observar el código, la lógica es muy simple. La función $ on recibe dos parámetros. El primero es el nombre del evento suscrito, que puede ser múltiple. Si hay varios, se pasa una matriz de nombres de eventos. La otra es la función de devolución de llamada. Primero, determine si el evento entrante es una matriz. Si lo es, recorra la matriz y llame de forma recursiva al método $ on para cada evento en la matriz para suscribirlo como un solo evento. Si no es una matriz, trátelo como un nombre de evento único, use el nombre del evento como clave, primero intente obtener la lista de eventos correspondiente en la propiedad _events de la instancia actual, si no está disponible, déle un vacío matriz como valor predeterminado y agregue la función de devolución de llamada del segundo parámetro.

Una frase más, ¿cuáles son los _eventos de la instancia? Aquí es cuando se inicializa el evento, el atributo _event está vinculado en la función initEvents y se le asigna un objeto vacío. Este atributo _events se utiliza como centro de eventos de la instancia actual, y todos los eventos vinculados a esta instancia se almacenarán en el atributo _events del centro de eventos.

Este es el principio interno de $ on.

Supongo que te gusta

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