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

相关推荐
云小遥16 分钟前
Cornerstone3D 2.x升级调研
前端·数据可视化
李明卫杭州21 分钟前
浅谈JavaScript中Blob对象
前端·javascript
springfe010121 分钟前
Cesium 3D地图 图元 圆柱 图片实现
前端·cesium
meng半颗糖24 分钟前
vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度
前端·javascript·css·vue.js·elementui·vue3
yt9483225 分钟前
jquery和CSS3圆形倒计时特效
前端·css3·jquery
teeeeeeemo27 分钟前
CSS3 动画基础与技巧
前端·css·笔记·css3
年纪轻轻就扛不住30 分钟前
CSS3 渐变效果
前端·css·css3
Aisanyi34 分钟前
【鸿蒙开发】使用HMRouter路由的使用
前端·harmonyos
杉木笙39 分钟前
Flutter 代码雨实现(矩阵雨)DLC 多图层
前端·flutter
SouthernWind40 分钟前
Vista AI 演示—— 提示词优化功能
前端·vue.js