中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue2模版指令元素綁定事件執行順序是什么

發布時間:2022-08-26 13:55:49 來源:億速云 閱讀:167 作者:iii 欄目:開發技術

這篇文章主要講解了“Vue2模版指令元素綁定事件執行順序是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Vue2模版指令元素綁定事件執行順序是什么”吧!

    Vue 自定義指令的執行機制

    version: 2.6.14

    前情提要

    某日,業務需要我需要在按鈕點擊之前驗證某些條件,如果不符合即不執行click內的業務代碼。思前想后,寫一個指令不就可以了。做到既不改動原有的業務代碼,又可以移植。

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

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

    實際一運行,發現1和2都打印出來了,而且1還是在2之前運行的。

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

    翻開谷歌,也沒有找到相關案例。

    DOM綁定

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

    元素上綁定的事件會轉換成vnode上的一個對象

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

    源碼

    那就找一找這個對象在哪邊使用的

    runtime中搜索addEventListener, 因為這個事件綁定上DOM中才有的事件,所以只會在web中了

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

    具體實現就先不管

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

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

    根據文件依次向上找????

    最終在modules/index.js中導出了

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

    函數一上來就把modules進行分類,把原來modules上的相關的對象進行合并,

    最終cbs會變成一個對象

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

    具體的執行的時機就不說了

    directive

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

    指令中對應以下幾個方法,也可以說是生命周期了

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

    接下來找找指令是什么時候初始化的

    全局查找directives, 其實就這一個文件,那就是它了

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

    可以明顯看到它也是在create內部周期上調用了bind方法了

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

    為什么先調用模版綁定的方法,再調用指令的方法

    回到patch.js, 可以看到模塊在這里進行了合并,把平臺相關的模塊放在前面,基礎指令和ref放在后面執行了。

    同時官方也進行了注釋,先執行內置的方法再執行指令的方法

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

    還是注釋沒仔細看,這個文件打開過多少次了。????

    改了就可以了嗎

    依舊不行。

    問題就在addEventListener身上

    拋開vue,看demo

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

    總結

    HTML 元素重復綁定同一個事件,后者并不會覆蓋前面的,只會有綁定的先后順序

    那之前的問題還能解么

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

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

    并且stopImmediatePropagation還用不了

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

    感謝各位的閱讀,以上就是“Vue2模版指令元素綁定事件執行順序是什么”的內容了,經過本文的學習后,相信大家對Vue2模版指令元素綁定事件執行順序是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    vue
    AI

    周宁县| 台前县| 南宫市| 和平县| 开江县| 福州市| 湾仔区| 嘉祥县| 秀山| 肥乡县| 衡南县| 锡林郭勒盟| 轮台县| 沾化县| 鄂伦春自治旗| 青龙| 长治市| 团风县| 万源市| 昌都县| 扎鲁特旗| 克拉玛依市| 阿拉善右旗| 横峰县| 修水县| 上饶县| 无为县| 出国| 舟曲县| 丁青县| 淮南市| 星座| 玉树县| 社旗县| 吉林市| 六枝特区| 安塞县| 安龙县| 汾西县| 珠海市| 云林县|