为什么自定义指令不生效?
背景
前端群内一位小伙问为什么使用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.