【问题标题】:Priority of Vue directives?Vue 指令的优先级?
【发布时间】:2019-08-08 13:39:27
【问题描述】:

我使用了第三方组件库的表单组件,它没有禁用道具,并且我通过@click 将单击事件绑定到每个表单项,以便在单击表单项时弹出一个对话框。但这是我的问题,在某些情况下表单项不应该是可点击的,所以我创建了一个自定义的 prevent-click 指令,如下所示:

const clickHandler = e => {
  e.stopImmediatePropagation()
  e.stopPropagation()
  return false
}

const directive = {
  bind(el, { value }) {
    if (value) {
      el.addEventListener('click', clickHandler, true)
    }
  },
  update(el, { value }) {
    if (!value) {
      el.removeEventListener('click', clickHandler, true)
    } else {
     el.addEventListener('click', clickHandler, true)
    }
  }
}

这样使用:

<form-item v-prevent-click="true" @click="showDialog"></form-item>

prevent-click 指令只向表单项添加一个捕获的事件侦听器,这会停止传播,到目前为止一切顺利,但问题是表单项有一个伪子元素被添加通过选择器后的 css。所以当我点击伪子元素时,由于伪子元素本身并没有派发click事件而不是form-item,所以form-item元素还是会派发事件,除了vue内置指令@click事件handler先绑定,导致addEventListener方法的useCapture参数不生效。

在 1.x 版本中,有自定义指令的优先选项,但 2.X 删除了它。那么有什么办法让我的自定义指令在内置@click之前绑定?

【问题讨论】:

  • 你能使用事件修饰符吗? vuejs.org/v2/guide/events.html#Event-Modifiers 并将阻止调用直接附加到@click?
  • emmmm,我已经检查了事件修饰符,但我认为它们不适用于我的情况......
  • 您也可以尝试添加e.preventDefault()

标签: javascript vue.js


【解决方案1】:

您应该使用 Vue 的内置事件修饰符(参考 here)。试试这个:

<form-item @click.stop.prevent="showDialog"></form-item>

我不知道你的第三方组件框架是什么,但是如果你真的需要自己处理preventDefault,我建议你这样做:

模板

<form-item @click="showDialog"></form-item>

脚本

methods: {
    showDialog(e) {
        e.preventDefault();
        // Your code to display dialog...
    }
}

如果您还需要将参数传递给showDialog,请记住您可以 - 只需将事件作为第一个参数传递:

<form-item @click="showDialog($event, urData)"></form-item>

【讨论】:

  • emmm,我真的不想更改 showDialog 代码,这就是我想使用自定义指令的原因。但是如果自定义指令绝对没有办法实现这一点,我会尝试
  • 我真的不知道你为什么需要这样做。 sharing more informations in your questions 呢?就像您正在使用的 3rd 方组件库一样,组件不应该是可点击的,为什么在您看来内置事件修饰符不起作用以及为什么您绝对需要自定义指令。
【解决方案2】:

考虑将标志传递给showDialog。如果您无法修改showDialog 函数,请将其包装在另一个函数中:

// Your compoennt template
<form-item @click="wrappedShowDialog(true)"></form-item>

// Vue.js component
wrappedShowDialog(isAllowed) {
    if (isAllowed) {
        this.showDialog();
    }
}

【讨论】:

    猜你喜欢
    • 2013-08-05
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多