[Vue2/Vue3] 你从未用过的隐藏技巧!Vue开发者必看

128 阅读1分钟

思考一个问题:Vue中如果你想监听子组件的生命周期,你会怎么办?

通过emit发出事件,这肯定是可行的:

// Child
<script setup>
import { onMounted } from "vue";

const emit = defineEmits(["childMounted"]);

onMounted(() => {
  // . . .
  emit("childMounted");
});
</script>


// App
<script setup>
import Child from "./Child.vue";

const childMounted = () => {
  console.log("child component onMounted execution"); 
};
</script>

<template>
  <Child @childMounted="childMounted" />
</template>

那如果子组件是第三方插件里面的应该怎么办呢?

隐藏技巧

先说Vue2,使用v-on:hook:[生命周期]指令:

<Child v-on:hook:mounted="handleClick" />
<Child @hook:mounted="handleClick" />

Vue3中可以使用另一个指令,使用v-on:vue:[生命周期]指令:

<Child v-on:vue:mounted="handleClick" />
<Child @vue:mounted="handleClick" />

源码解读

官方文档没有该记载,我翻阅Vue3源码在vOn部分有这个实现:

if (arg.isStatic) {
  let rawName = arg.content
  if (__DEV__ && rawName.startsWith('vnode')) {
    context.onError(createCompilerError(ErrorCodes.X_VNODE_HOOKS, arg.loc))
  }
  if (rawName.startsWith('vue:')) {
    rawName = `vnode-${rawName.slice(4)}`
  }
  const eventString =
    node.tagType !== ElementTypes.ELEMENT ||
    rawName.startsWith('vnode') ||
    !/[A-Z]/.test(rawName)
      ? // for non-element and vnode lifecycle event listeners, auto convert
        // it to camelCase. See issue #2249
        toHandlerKey(camelize(rawName))
      : // preserve case for plain element listeners that have uppercase
        // letters, as these may be custom elements' custom events
        `on:${rawName}`
  eventName = createSimpleExpression(eventString, true, arg.loc)
} else {
  // #2388
  eventName = createCompoundExpression([
    `${context.helperString(TO_HANDLER_KEY)}(`,
    arg,
    `)`,
  ])
}

这段代码是位置transformOn 函数内,transformOn是 Vue 3 的内部指令转换函数,用于处理 v-on 指令。

该函数将 v-on 指令转换为可执行的 JavaScript 代码。在 Vue 编译过程中,这个函数会将模板中的 v-on 指令转换为渲染函数所需的格式。

事件名处理逻辑

  • 如果事件名称是静态的 (arg.isStatic) 且以 vue: 开头,会被转换为 vnode- 事件(例如 vue:mounted 会变为 vnode-mounted)。

  • 对于一般的事件名称,会转换为 on: 前缀的形式,或者对一些非 DOM 元素和以 vnode 开头的事件名进行处理。

  • 代码中的 vnode- 前缀处理逻辑,说明 Vue 允许开发者通过 v-on 监听自定义的 vnode 生命周期事件。

总结

该方法不是推荐的公共 API,没有出现在官方文档。这种写法出现在项目的内部实现中,大家可以进一步研究其实现细节。

感谢您的阅读!

22.gif