vue中可以綁定多個事件嗎
vue可以綁定多個事件嗎
標(biāo)簽綁定一個事件處理函數(shù),然后在相應(yīng)的事件處理函數(shù)中調(diào)用想要觸發(fā)的多個處理函數(shù)
以下兩種方案,都可以實施
第一種
<button id="test" @click="test1">按鈕</button>
new Vue({ ? ? el:"#test", ? ? data:"", ? ? methods:{ ? ? ? ? test1:function(){ ? ? ? ? ? ? alert("test1"); ? ? ? ? ? ? this.test2(); ? ? ? ? ? ? this.test3(); ? ? ? ? }, ? ? ? ? test2:function(){ ? ? ? ? ? ? alert("test2"); ? ? ? ? }, ? ? ? ? test3:function(){ ? ? ? ? ? ? alert("test3"); ? ? ? ? } ? ? } })
第二種
綁定多個事件時,事件之間使用分號“;”分開即可
<el-button type="primary" size="small" @click="add1();add2();">123</el-button>
去methods中添加事件的函數(shù)
methods:{ ? ? add1(){ ? ? ? ? console.log(123) ? ? }, ? ? add2(){ ? ? ? ? console.log(456) ? ? }, ? ? }
vue事件綁定的原理
之前我搜這個原理的時候,好多文章,都只寫了兩句話:
- 原生事件綁定是通過addEventListener綁定給真實元素的。
- 組件事件綁定是通過Vue自定義的key$on實現(xiàn)的。
那具體是怎么實現(xiàn)的呢, 沒有說?
就現(xiàn)在具體看一下。
// 原生事件綁定 <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}}
兩者編譯出來不一樣
// 前者 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 在創(chuàng)建真是 dom 時會調(diào)用 createElm ,默認(rèn)會調(diào)用 invokeCreateHooks
- 會遍歷當(dāng)前平臺下相對的屬性處理代碼,其中就有 updateDOMListeners 方法,內(nèi)部會傳入 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( // 給當(dāng)前的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 方法來實現(xiàn)的
1.3 $on 是怎么實現(xiàn)的
vm.$on( event, callback )
作用:
監(jiān)聽當(dāng)前實例上的自定義事件。事件可以由vm.$emit觸發(fā)?;卣{(diào)函數(shù)會接收所有傳入事件觸發(fā)函數(shù)的額外參數(shù)。
原理:
$on是采用了經(jīng)典的發(fā)布訂閱者設(shè)計模式,首先定義一個事件中心,通過$on訂閱事件,將事件存儲在事件中心里面,然后通過$emit觸發(fā)事件中心里面存儲的訂閱事件。
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函數(shù)接收倆個參數(shù),第一個是訂閱的事件名,可以是多個,如果是多個就傳入一個事件名數(shù)組。另一個是回調(diào)函數(shù)。
首先判斷傳入的事件是不是一個數(shù)組,如果是,那么遍歷這個數(shù)組,將數(shù)組中的每一個事件都遞歸調(diào)用$on方法將其作為單個事件訂閱。
如過不是數(shù)組,那就當(dāng)做單個事件名來處理,以該事件名作為key,先嘗試在當(dāng)前實例的_events屬性中獲取其對應(yīng)的事件列表,如果獲取不到就給其賦空數(shù)組為默認(rèn)值,并將第二個參數(shù)回調(diào)函數(shù)添加進去。
多說一句,實例的_events是什么?這就是在事件初始化的時候,initEvents函數(shù)中綁定了_event屬性并給其賦值為空對象。這個_events屬性就是用來作為當(dāng)前實例的事件中心,所有綁定在這個實例上的事件都會存儲在事件中心_events屬性中。
這就是$on的內(nèi)部原理。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Vue 組件事件觸發(fā)和監(jiān)聽實現(xiàn)源碼解析
- Vue?click事件傳遞參數(shù)的示例教程
- vue中@click綁定事件點擊不生效的原因及解決方案
- Vue中使用element-ui給按鈕綁定一個單擊事件實現(xiàn)點擊按鈕就彈出dialog對話框
- vue中如何給el-table-column添加指定列的點擊事件
- vue長按事件和點擊事件沖突的解決
- vue項目如何實現(xiàn)Echarts在label中獲取點擊事件
- Vue Element-ui 鍵盤事件失效的解決
- Vue如何給組件添加點擊事件?@click.native
- vue中的事件觸發(fā)(emit)及監(jiān)聽(on)問題
- vant/vue手機端長按事件以及禁止長按彈出菜單實現(xiàn)方法詳解
相關(guān)文章
element-ui中導(dǎo)航組件menu的一個屬性:default-active說明
這篇文章主要介紹了element-ui中導(dǎo)航組件menu的一個屬性:default-active說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05van-picker組件default-index屬性設(shè)置不生效踩坑及解決
這篇文章主要介紹了van-picker組件default-index屬性設(shè)置不生效踩坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01Vue2(三)實現(xiàn)子菜單展開收縮,帶動畫效果實現(xiàn)方法
這篇文章主要介紹了vue實現(xiàn)收縮展開效果的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04vue+iview如何實現(xiàn)拼音、首字母、漢字模糊搜索
這篇文章主要介紹了vue+iview如何實現(xiàn)拼音、首字母、漢字模糊搜索,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04