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