Vueでのイベントバインディングの原則

以前にこの原則を検索したとき、私は多くの記事に2つの文しか書きませんでした。

ネイティブイベントバインディングは、addEventListenerを介して実際の要素にバインドされます。
コンポーネントイベントのバインドは、Vueのカスタムkey $ onを介して実現されます。

それはどのように起こったのですか?
それを見てみましょう。

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

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

原則:
イベントの編集:

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}}

コンパイルされた2つは同じではありません

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

ここに画像の説明を挿入

1.1ネイティブdomのバインディング

  • Vueは実際のDOMを作成するときにcreateElmを呼び出し、invokeCreateHooksはデフォルトで呼び出されます
  • updateDOMListenersメソッドを含む、現在のプラットフォームでの相対属性処理コードをトラバースし、addメソッドは内部で渡されます

ソースコード:

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コンポーネントのバインディングイベント

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) 
}

コンポーネントバインディングイベントは、vueのカスタム$ onメソッドを介して実装されます

1.3 $ onはどのように機能しますか?

vm.$on( event, callback )

効果:

現在のインスタンスでカスタムイベントをリッスンします。イベントはvm。$ emitによってトリガーできます。コールバック関数は、着信イベントトリガー関数のすべての追加パラメーターを受け取ります。

原理:

$ onは、従来のパブリッシュ/サブスクライバーデザインパターンを採用しています。まず、イベントセンターを定義し、$ onを介してイベントをサブスクライブし、イベントをイベントセンターに格納してから、$ 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
}

コードを見ると、ロジックは非常に単純です。$ on関数は2つのパラメーターを受け取ります。最初のパラメーターは、サブスクライブされたイベントの名前であり、複数の場合があります。複数ある場合は、イベント名の配列が渡されます。もう1つはコールバック関数です。まず、着信イベントが配列であるかどうかを判断します。配列である場合は、配列をトラバースし、配列内の各イベントに対して$ onメソッドを再帰的に呼び出して、単一のイベントとしてサブスクライブします。配列でない場合は、単一のイベント名として扱い、イベント名をキーとして使用します。まず、現在のインスタンスの_eventsプロパティで対応するイベントリストを取得しようとします。使用できない場合は、空にします。配列をデフォルト値として使用し、2番目のパラメーターコールバック関数を追加します。

もう1つの文、インスタンスの_eventsは何ですか?これは、イベントが初期化されるときに、_event属性がinitEvents関数にバインドされ、空のオブジェクトが割り当てられるときです。この_events属性は、現在のインスタンスのイベントセンターとして使用され、このインスタンスにバインドされているすべてのイベントは、イベントセンターの_events属性に格納されます。

これが$ onの内部原則です。

おすすめ

転載: blog.csdn.net/Beth__hui/article/details/114089801