为什么自定义指令不生效?
背景
前端群内一位小伙问为什么使用vue3+antd-vue,将自定义指令绑定到AImage
组件上不生效呢
自定义指令
众所周知,自定义指令只有在直接操作dom时才应该使用.且官网介绍不推荐在组件上使用自定义指令。当组件具有多个根节点时可能会出现预期外的行为。
源码分析
AImage源码
return wrapSSR(
<ImageInternal
{...{ ...attrs, ...props, prefixCls: prefixCls.value }}
preview={mergedPreview.value}
rootClassName={classNames(props.rootClassName, hashId.value)}
v-slots={{
...slots,
previewMask: typeof previewMask === 'function' ? previewMask : null,
}}
></ImageInternal>,
发现AImage实际渲染的是ImageInternal
组件.
ImageInternal源码分析
return (
<>
<div
class={wrappperClass}
onClick={
canPreview.value
? onPreview
: e => {
emit('click', e);
}
}
style={{
width: toSizePx(width),
height: toSizePx(height),
...wrapperStyle,
}}
>
...
</>
ImageInternal对应的打包后产物
return (0, _vue.createVNode)(_vue.Fragment, null, [(0, _vue.createVNode)("div", {
"class": wrappperClass,
"onClick": canPreview.value ? onPreview : e => {
emit('click', e);
},
"style": (0, _extends2.default)({
width: toSizePx(width),
height: toSizePx(height)
}, wrapperStyle)
}, [(0, _vue.createVNode)("img", (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, imgCommonProps), isError.value && fallback ? {
src: fallback
})
会发现最外层创建了一个VNode,对应标签为_vue.Fragment,类似jsx中的<>,故而自定指令绑定AImage后拿不到对应的el.