亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue2?模版指令元素綁定事件執(zhí)行順序解析

 更新時(shí)間:2022年08月26日 11:58:29   作者:JunIce  
這篇文章主要為大家介紹了Vue2?模版指令元素綁定事件執(zhí)行順序解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Vue 自定義指令的執(zhí)行機(jī)制

version: 2.6.14

前情提要

某日,業(yè)務(wù)需要我需要在按鈕點(diǎn)擊之前驗(yàn)證某些條件,如果不符合即不執(zhí)行click內(nèi)的業(yè)務(wù)代碼。思前想后,寫一個(gè)指令不就可以了。做到既不改動(dòng)原有的業(yè)務(wù)代碼,又可以移植。

<template>
  <button v-capture @click="handleClick">button</button>
</template>
<script>
  export default {
    methods: {
      handleClick(){
        console.log(1)
      }
    },
    directives: {
      capture: {
        bind(el) {
          el.captureHandler = (e) => {
            // 驗(yàn)證條件
            console.log(2)
            e.stopPropagation()
          };
          el.addEventListener("click", el.captureHandler);
        },
        unbind(el) {
          el.removeEventListener("click", el.captureHandler);
        }
      }
    }
}
</script>

以上就是偽代碼,乍一看沒啥問題。

實(shí)際一運(yùn)行,發(fā)現(xiàn)1和2都打印出來了,而且1還是在2之前運(yùn)行的。

這樣一看模版上綁定的事件執(zhí)行是在自定義指令綁定事件之前的。

翻開谷歌,也沒有找到相關(guān)案例。

DOM綁定

我們都知道vue的SFC最終還是會(huì)被編譯成js文件,最終模板會(huì)被編譯成vnode,

元素上綁定的事件會(huì)轉(zhuǎn)換成vnode上的一個(gè)對(duì)象

{
  // ....
  on: {
    click: 'handleClick'
  }
}

源碼

那就找一找這個(gè)對(duì)象在哪邊使用的

runtime中搜索addEventListener, 因?yàn)檫@個(gè)事件綁定上DOM中才有的事件,所以只會(huì)在web中了

// src/platforms/web/runtime/modules/events.js
export default {
  create: updateDOMListeners,
  update: updateDOMListeners,
  destroy: (vnode: VNodeWithData) => updateDOMListeners(vnode, emptyNode)
}

具體實(shí)現(xiàn)就先不管

updateDOMListeners中通過調(diào)用了updateListeners方法,把事件綁定到元素上去

還有就是返回了一個(gè)對(duì)象,包括create、update、destroy, 這不是很像vue的生命周期函數(shù)命名嘛

根據(jù)文件依次向上找??

最終在modules/index.js中導(dǎo)出了

export default [
  attrs,
  klass,
  events,
  domProps,
  style,
  transition
]

modules最終在哪里使用的?

就是大名鼎鼎的patch.js

// src/core/vdom/patch.js

const { modules, nodeOps } = backend

for (i = 0; i < hooks.length; ++i) {
  cbs[hooks[i]] = []
  for (j = 0; j < modules.length; ++j) {
    if (isDef(modules[j][hooks[i]])) {
      cbs[hooks[i]].push(modules[j][hooks[i]])
    }
  }
}

函數(shù)一上來就把modules進(jìn)行分類,把原來modules上的相關(guān)的對(duì)象進(jìn)行合并,

最終cbs會(huì)變成一個(gè)對(duì)象

const cbs = {
  create: [fn1, fn2, fn3],
  update: [fn1, fn2, fn3],
  destroy: [fn1, fn2, fn3],
}

具體的執(zhí)行的時(shí)機(jī)就不說了

directive

指令是vue的一大特色了,源于angularjs中就有指令這個(gè)東西了,vue3中依舊保留了下來

指令中對(duì)應(yīng)以下幾個(gè)方法,也可以說是生命周期了

directives: {
  name: {
		bind(){},
    insert(){},
    inserted(){},
    componentUpdated(){},
    update(){},
    unbind(){},
  }
}

接下來找找指令是什么時(shí)候初始化的

全局查找directives, 其實(shí)就這一個(gè)文件,那就是它了

// src/core/vdom/modules/directives.js
{
  create: updateDirectives,
  update: updateDirectives,
  destroy: function unbindDirectives (vnode: VNodeWithData) {
    updateDirectives(vnode, emptyNode)
  }
}

可以明顯看到它也是在create內(nèi)部周期上調(diào)用了bind方法了

callHook(dir, 'bind', vnode, oldVnode)

為什么先調(diào)用模版綁定的方法,再調(diào)用指令的方法

回到patch.js, 可以看到模塊在這里進(jìn)行了合并,把平臺(tái)相關(guān)的模塊放在前面,基礎(chǔ)指令和ref放在后面執(zhí)行了。

同時(shí)官方也進(jìn)行了注釋,先執(zhí)行內(nèi)置的方法再執(zhí)行指令的方法。

// src/platforms/web/runtime/patch.js
import baseModules from 'core/vdom/modules/index'
import platformModules from 'web/runtime/modules/index'

// the directive module should be applied last, after all
// built-in modules have been applied.
const modules = platformModules.concat(baseModules)

還是注釋沒仔細(xì)看,這個(gè)文件打開過多少次了。??

改了就可以了嗎

依舊不行。

問題就在addEventListener身上

拋開vue,看demo

const btn = document.querySelector('#btn')
btn.addEventListener('click', () => {
  console.log(1)
})
btn.addEventListener('click', () => {
  console.log(2)
})

總結(jié)

HTML 元素重復(fù)綁定同一個(gè)事件,后者并不會(huì)覆蓋前面的,只會(huì)有綁定的先后順序

那之前的問題還能解么

在捕獲階段執(zhí)行事件, 如果不符合條件,則停止事件傳遞。

el.addEventListener("click", el.captureHandler, true);

并且stopImmediatePropagation還用不了

stopImmediatePropagation可以阻止元素上綁定的其他事件,但是也是按添加順序,阻止之后的事件執(zhí)行

以上就是Vue2 模版指令元素綁定事件執(zhí)行順序解析的詳細(xì)內(nèi)容,更多關(guān)于Vue2 事件執(zhí)行順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 讓 babel webpack vue 配置文件支持智能提示的方法

    讓 babel webpack vue 配置文件支持智能提示的方法

    這篇文章主要介紹了讓 babel webpack vue 配置文件支持智能提示的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • vue?+elementui?項(xiàng)目登錄通過不同賬號(hào)切換側(cè)邊欄菜單的顏色

    vue?+elementui?項(xiàng)目登錄通過不同賬號(hào)切換側(cè)邊欄菜單的顏色

    這篇文章主要介紹了vue?+elementui?項(xiàng)目登錄通過不同賬號(hào)切換側(cè)邊欄菜單的顏色,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • Vue組件上使用v-model之單選框

    Vue組件上使用v-model之單選框

    這篇文章主要介紹了Vue組件上使用v-model之單選框,代碼分為子組件內(nèi)容和父組件內(nèi)容,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • vue中g(shù)et請(qǐng)求如何傳遞數(shù)組參數(shù)的方法示例

    vue中g(shù)et請(qǐng)求如何傳遞數(shù)組參數(shù)的方法示例

    這篇文章主要介紹了vue中g(shù)et請(qǐng)求如何傳遞數(shù)組參數(shù)的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Vue+scss白天和夜間模式切換功能的實(shí)現(xiàn)方法

    Vue+scss白天和夜間模式切換功能的實(shí)現(xiàn)方法

    這篇文章主要介紹了Vue+scss白天和夜間模式切換功能的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • vue 組件內(nèi)獲取actions的response方式

    vue 組件內(nèi)獲取actions的response方式

    今天小編就為大家分享一篇vue 組件內(nèi)獲取actions的response方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue項(xiàng)目查看vue版本及cli版本的實(shí)現(xiàn)方式

    vue項(xiàng)目查看vue版本及cli版本的實(shí)現(xiàn)方式

    這篇文章主要介紹了vue項(xiàng)目查看vue版本及cli版本的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 使用Vant如何完成各種Toast提示框

    使用Vant如何完成各種Toast提示框

    這篇文章主要介紹了使用Vant如何完成各種Toast提示框,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 關(guān)于vue編譯版本引入的問題的解決

    關(guān)于vue編譯版本引入的問題的解決

    這篇文章主要介紹了關(guān)于vue編譯版本引入的問題的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue如何使用AIlabel標(biāo)注組件

    vue如何使用AIlabel標(biāo)注組件

    這篇文章主要介紹了vue如何使用AIlabel標(biāo)注組件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論