Vue2中button元素和RouterLink组件的公共onClick事件侦听器



在下面的代码中,component可以是buttoninputRouterLink,我们事先不知道会是哪一个。我添加了很多属性来阻止v-if解决方案,因为在这种情况下,我们需要复制大多数属性:

<component 
:is="rootElementTagOrComponentName" 
@click.prevent="$emit('click', $event.target)"
:to="route" 
:type="inputOrButtonElementTypeAttributeValue" 
:class="CSS_Classes" 
:value="rootElementTagNameIsInput &amp;&amp; lettering" 
:role="rootElementIsLink && 'link'" 
:disabled="(rootElementTagNameIsButton || rootElementTagNameIsInput) &amp;&amp; disabled"
:ref="ROOT_ELEMENT_REFERENCE"
>
<template v-if="!rootElementTagNameIsInput && lettering">{{ lettering }}</template>
<slot v-if="!rootElementTagNameIsInput"></slot>
</component>

@click.prevent="$emit('click', $event.target)"不适用于RoterLink。然而,使用@click.native.prevent="$emit('click', $event.target)",我们得到

[Vue warn]: The .native modifier for v-on is only valid on components but it was used on <button>.

如何解决这一冲突?

当您有一个动态组件,可能是也可能不是本机元素时,这会变得很棘手。不幸的是,单独在模板中没有简单的方法可以做到这一点,您必须在代码中完成(v-on对象语法不支持本机事件(。

未经测试,但类似的东西可能会起作用:

<Root
:to="route"
:type="inputOrButtonElementTypeAttributeValue" 
:class="CSS_Classes" 
:value="rootElementTagNameIsInput &amp;&amp; lettering" 
:role="rootElementIsLink && 'link'" 
:disabled="(rootElementTagNameIsButton || rootElementTagNameIsInput) &amp;&amp; disabled"
:ref="ROOT_ELEMENT_REFERENCE"
>
<template v-if="!rootElementTagNameIsInput && lettering">{{ lettering }}</template>
<slot v-if="!rootElementTagNameIsInput"></slot>
</Root>
components: {
Root: {
functional: true,
render(h, ctx) {
const { data, parent, children } = ctx
const tag = parent.rootElementTagOrComponentName
const click = e => {
e.preventDefault()
parent.$emit('click', e.target)
}
if (tag === 'RouterLink') {
data.nativeOn = data.nativeOn || {}
data.nativeOn.click = click
} else {
data.on = data.on || {}
data.on.click = click
}
return h(tag, data, children)
}
}
}

我在代码中所做的只是注册点击事件,但如果您愿意,也可以将其他内容移动到代码中。

最新更新