Vue老鸟?那你肯定知道监控生命周期的技巧吧!

前言

Hello~大家好。我是秋天的一阵风

在 Vue 的世界里,生命周期钩子是每个组件成长的见证。从组件的出生到消逝,每个阶段都有特定的钩子,让我们可以洞察并参与组件的每一个重要时刻。但是,当被问到 "如何监听这些生命周期事件" 这个问题时,你是否能迅速回答出来?或者,你是否突然感到有些迷茫?

在我们揭晓答案之前,让我们先简单回顾一下 Vue 2 和 Vue 3 的生命周期知识。这将帮助我们更好地理解如何监听这些关键的生命周期事件。

一、Vue2 与 Vue3 生命周期的区别

Vue 2 生命周期钩子 Vue 3 生命周期钩子 描述
beforeCreate 无直接对应 在 Vue 3 中,beforeCreate 的功能被 setup() 钩子覆盖。在 setup() 中,你可以访问到 props 和 context,但不能访问到 this。
created setup() 在 Vue 3 中,created 的功能被 setup() 钩子覆盖。在 setup() 中,你可以访问到 props 和 context,但不能访问到 this。
beforeMount onBeforeMount 在组件挂载到 DOM 之前调用。
mounted onMounted 在组件挂载完成后调用。
beforeUpdate onBeforeUpdate 在组件即将更新之前调用。
updated onUpdated 在组件更新后调用。
beforeDestroy onBeforeUnmount 在组件即将卸载之前调用。
destroyed onUnmounted 在组件卸载后调用。
errorCaptured onErrorCaptured 当捕获一个来自子孙组件的错误时被调用。

🎯 关于 errorCaptured 生命周期

errorCaptured 是一个相对冷门但极其强大的生命周期钩子,它允许你在组件及其子组件中捕获未处理的错误。这对于全局错误监控和自定义错误处理策略非常有用。

如果你对这个钩子感兴趣,强烈推荐你阅读以下文章,深入了解其工作原理和应用场景:

🔎 深入 Vue 3 生命周期的源码实现

如果你对 Vue 3 生命周期的源码实现感兴趣,或者想了解 Vue 3 生命周期钩子的执行过程,以下文章将为你揭开神秘的面纱:

除此之外,Vue.js 3.0 还新增了两个用于调试的生命周期 API:onRenderTracked 和 onRenderTriggered。

更多的生命周期API信息你可以在这里阅读:组合式API:生命周期钩子

二、Vue2中监听生命周期

我们来看一个简单的例子,下面代码例子中注册了多个生命周期方法,在组件对应的生命周期中会执行。

html 复制代码
<template>
  <div>
    <h1>Vue 2 生命周期示例</h1>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      message: "Hello Vue 2",
    };
  },
  beforeCreate() {
    console.log("beforeCreate: 实例刚刚被创建,data 和 methods 还未初始化");
  },
  created() {
    console.log("created: 实例创建完成,data 和 methods 已初始化");
  },
  beforeMount() {
    console.log("beforeMount: 挂载开始之前,模板已编译,但尚未挂载到 DOM");
  },
  mounted() {
    console.log("mounted: 挂载完成,模板已渲染到 DOM");
  },
  beforeUpdate() {
    console.log("beforeUpdate: 数据更新之前,虚拟 DOM 还未更新");
  },
  updated() {
    console.log("updated: 数据更新完成,虚拟 DOM 和真实 DOM 都已更新");
  },
  beforeDestroy() {
    console.log("beforeDestroy: 实例销毁之前,组件仍然可用");
  },
  destroyed() {
    console.log("destroyed: 实例销毁完成,组件已不可用");
  },
  errorCaptured(err, vm, info) {
    console.error("errorCaptured: 捕获来自子组件的错误");
    console.error("Error:", err);
    console.error("Component:", vm);
    console.error("Error Info:", info);
    return false; // 返回 false 可以阻止错误继续向上冒泡
  },
};
</script>

<script>
export default {
  components: {},
};
</script>

在开发过程中,我们常常会发现业务逻辑分散在各个生命周期钩子中,这种分散的代码结构有时会降低代码的可读性,尤其是当业务逻辑复杂且代码量较大时。这种情况下,代码的维护和理解成本会显著增加。

为了解决这一问题,我们可以巧妙地利用 Vue 提供的 hook: 语法来集中管理某一块的业务逻辑。通过这种方式,我们可以将相关的业务逻辑集中到一个特定的生命周期钩子中,从而让代码结构更加清晰,逻辑更加连贯,显著提升代码的可读性和可维护性。

1.this.$on("hook:mounted")用法

html 复制代码
<template>
  <div>
    <h1>Vue 2 生命周期示例</h1>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      message: "Hello Vue 2",
    };
  },
  created() {
    console.log("created: 实例创建完成,data 和 methods 已初始化");

    this.$on("hook:mounted", () => {
      console.log("mounted 挂载触发")
    });
    this.$on("hook:updated", () => {
      // 挂载时执行一些业务A相关逻辑;
    });
  },
};
</script>

<script>
export default {
  components: {},
};
</script>

2. @hook监听子组件生命周期

那如果我想监听一个组件的生命周期呢?其实也是可以的。

我们可以直接用@hook来监听子组件的生命周期

js 复制代码
<template>
  <div>
    <h1>Vue 2 生命周期示例</h1>
    <button @click="handleClick()">
      {{ show ? "销毁子组件" : "展示子组件" }}
    </button>
    <ChildComponent
      v-if="show"
      @hook:mounted="handleChildMounte"
      @hook:destroyed="handleChildDestroyed"
    />
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue";
export default {
  name: "App",
  components: {
    ChildComponent,
  },
  data() {
    return {
      show: false,
    };
  },
  methods: {
    handleClick() {
      this.show = !this.show;
    },

    handleChildMounte() {
      console.log("子组件挂载完成");
    },
    handleChildDestroyed() {
      console.log("子组件销毁完成");
    },
  },
};
</script>
<style scoped>
click-btn {
  padding: 10px 20px;
  background-color: #333;
  color: #fff;
  border: 1px solid #333;
  cursor: pointer;
}
</style>
js 复制代码
// ChildComponent.vue
<template>
  <div>
    <h2>我是子组件</h2>
  </div>
</template>

<script>
export default {
  methods: {},
};
</script>

三、Vue3中监听生命周期

Vue3中只需要将hook替换为vue即可,我们看看代码和效果:

js 复制代码
<template>
  <div>
    <h1>Vue 3 生命周期示例</h1>
    <button @click="handleClick" class="click-btn">
      {{ show ? "销毁子组件" : "展示子组件" }}
    </button>
    <ChildComponent
      v-if="show"
      @vue:mounted="handleChildMounted"
      @vue:unmounted="handleChildUnmounted"
    />
  </div>
</template>

<script>
import { ref } from "vue";
import ChildComponent from "./ChildComponent.vue";

export default {
  name: "App",
  components: {
    ChildComponent,
  },
  setup() {
    const show = ref(false);

    const handleClick = () => {
      show.value = !show.value;
    };

    const handleChildMounted = () => {
      console.log("子组件挂载完成");
    };

    const handleChildUnmounted = () => {
      console.log("子组件销毁完成");
    };

    return {
      show,
      handleClick,
      handleChildMounted,
      handleChildUnmounted,
    };
  },
};
</script>

<style scoped>
.click-btn {
  padding: 10px 20px;
  background-color: #333;
  color: #fff;
  border: 1px solid #333;
  cursor: pointer;
}
</style>

🚀🚀🚀

更多详细内容,你可以查看官方的迁移指南: Vue3迁移指南VNode 生命周期事件

相关推荐
特创数字科技35 分钟前
一个纯本地运行的图片处理工具:压缩 / 裁剪 / 九宫格 / 圆角 / 滤镜 / 拼图 / 水印,终生使用
前端
IT_陈寒1 小时前
Vue的v-if和v-for混用居然是个天坑
前端·人工智能·后端
天衍四九-1 小时前
【无标题】
前端·spring boot·mysql·nginx·docker
广州华水科技1 小时前
2026年单北斗GNSS变形监测系统推荐榜单,解锁GNSS位移监测新高度
前端
xcyxiner1 小时前
DicomViewer24 修复编译bug(window test 失败)
前端·qt
linux_cfan2 小时前
videojs v10 源代码系列解读:34 · `createComposition`:类型安全的冲突检测
前端·安全
utmhikari3 小时前
【AI原生】借助AI之力优化个人博客前端样式
前端·css·hexo·next·个人博客·ai-native·vibe coding
小溪学编程3 小时前
从 C++ 的规范变迁看语言发展
jvm·c++·面试
小凯在掘金4 小时前
为什么箭头函数不能作为构造函数?
前端·javascript