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

前言

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

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

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

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

Vue 2 生命周期钩子 Vue 3 生命周期钩子 描述
beforeCreate 无直接对应 在 Vue 3 中,beforeCreate 的功能被 setup() 钩子覆盖。在 setup() 中,你可以访问到 propscontext,但不能访问到 this
created setup() 在 Vue 3 中,created 的功能被 setup() 钩子覆盖。在 setup() 中,你可以访问到 propscontext,但不能访问到 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:onRenderTrackedonRenderTriggered

更多的生命周期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 生命周期事件

相关推荐
Mr_Mao1 小时前
Naive Ultra:中后台 Naive UI 增强组件库
前端
前端小趴菜052 小时前
React-React.memo-props比较机制
前端·javascript·react.js
摸鱼仙人~3 小时前
styled-components:现代React样式解决方案
前端·react.js·前端框架
sasaraku.4 小时前
serviceWorker缓存资源
前端
RadiumAg5 小时前
记一道有趣的面试题
前端·javascript
yangzhi_emo5 小时前
ES6笔记2
开发语言·前端·javascript
yanlele5 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
中微子6 小时前
React状态管理最佳实践
前端
烛阴7 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
小兵张健7 小时前
武汉拿下 23k offer 经历
java·面试·ai编程