vue 自定义指令点击事件比v-on执行的晚?

html

<el-button @click="initGetTreeList" v-track-event>测试</el-button>

v-track-event 自定义指令

  bind: function (el, binding, VNone) {
      //需要执行的事件
        el.onclick = function () {
          console.log('点击');
        }
        el.addEventListener('click', () => {
          console.log('点击2');
         }, true)
    }

元素事件

 initGetTreeList () {
    console.log('项目');
 }

打印的顺序

    项目中的`initGetTreeList`要比自定义指令走的快

如何实现自定义指令中的事件先走

阅读 6.5k
3 个回答

元素在创建的时候会调用invokeCreateHooks方法,它会去遍历cbs.create中钩子函数进行执行,cbs.create中的钩子函数如下图所示共8个。

cbs.create

执行指令的updateDirectives函数在最后执行,而绑定事件的updateDOMListeners函数早于updateDirectives函数。

所以从vue源码上来说,自定义指令的点击事件是晚于v-on执行的。所以你只能另辟蹊跷了,比如你讲的利用冒泡把事件绑到父元素上,这样他就属于父元素的事件,子元素会优先于父元素冒泡事件。

楼上分析的很对,

我的建议是,你改造下自定义指令,把需要执行的业务函数 和当前业务函数需要的上下文,通过参数的形式传给指令。

新手上路,请多包涵

vue的自定义指令在编写前端埋点时能省不少力气,这个问题可以用事件捕捉来解决,在自定义指令中定义

Vue.directive("stat", {
  inserted: (el, binding, vnode) => {
    // 如果没有权限就移除此节点
    // console.log(binding.value, !hasPermission(binding.value))
    if (!hasPermission(binding.value)) {
      // 移除元素有时会考虑到一个 按钮容器  里面的按钮都移除后  应该删掉
      // 因此多个元素 决定 可以使用数组 []
      //  单个按钮使用string
      if (Object.prototype.toString.call(binding.value) === "[object String]") {
        el.parentNode.removeChild(el);
      } else {
        el.style.display = "none"
      }
    }
  },
  bind (el, binding) {
    // 点击事件设置为冒泡捕获  由外层触发  优先于vue原生绑定的v-on  
    // 先绑定当前buttonId 再发送ajax
    el.addEventListener("click", () => {
      // 点击绑定的为特定的string
      const data = binding.value
      store.state.buttonId = getButtonId(data)
    }, true)
  }
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题