深入理解Vue 生命周期

Vue 生命周期:从 Vue2 到 Vue3 的演进

在 Vue.js 的世界里,生命周期是理解组件运作机制的关键。它如同一条无形的线索,贯穿组件从诞生到消亡的整个过程。今天,我们就来深入剖析 Vue 的生命周期,从 Vue3 的基础概念入手,再对比 Vue2 的差异,通过丰富的代码示例,让你对 Vue 的生命周期有全方位的理解。

Vue3 生命周期

Vue3 的生命周期主要划分为三个核心阶段:挂载(mount)、更新(update)和卸载(unmount)。这三个阶段如同组件的 "成长轨迹",每个阶段都伴随着特定的钩子函数,为开发者提供了在不同时机执行自定义逻辑的能力。

挂载阶段

挂载阶段决定了组件如何被渲染到页面上。在这个阶段,onBeforeMount和onMounted这两个钩子函数发挥着重要作用。

onBeforeMount钩子函数在组件挂载到 DOM 之前触发。此时,组件的模板已经编译完成,但真实的 DOM 节点还未被创建。我们可以利用这个钩子函数进行一些前期准备工作,比如记录日志。

javascript 复制代码
import { onBeforeMount } from 'vue';
export default {
  setup() {
    onBeforeMount(() => {
      console.log('组件即将挂载,正在进行准备工作');
    });
  }
};

当onBeforeMount执行完毕,Vue 会继续将组件挂载到 DOM 上,随后onMounted钩子函数被触发。这个时候,组件已经成功挂载到页面,我们可以在这里执行需要访问 DOM 的操作。例如,使用 Echarts 库绘制图表,或者初始化 Swiper 幻灯片插件。

javascript 复制代码
import { onMounted } from 'vue';
import echarts from 'echarts';
export default {
  setup() {
    onMounted(() => {
      const chartDom = document.getElementById('main');
      const myChart = echarts.init(chartDom);
      const option = {
        // Echarts图表配置项
      };
      myChart.setOption(option);
    });
  }
};

更新阶段

随着组件状态的变化,更新阶段随之而来。onBeforeUpdate和onUpdated这两个钩子函数在这个阶段发挥作用。

onBeforeUpdate钩子函数在组件数据更新之前被调用。此时,组件的状态已经发生改变,但 DOM 还未更新。在这个时机,我们可以进行一些数据更新前的准备工作,比如备份旧数据。

javascript 复制代码
import { ref, onBeforeUpdate } from 'vue';
export default {
  setup() {
    const count = ref(0);
    let oldCount;
    onBeforeUpdate(() => {
      oldCount = count.value;
      console.log('数据即将更新,旧值为', oldCount);
    });
    return {
      count
    };
  }
};

当onBeforeUpdate执行完毕,Vue 会更新 DOM。之后,onUpdated钩子函数被触发。在这个时候,DOM 已经更新完成,我们可以进行依赖于更新后 DOM 的操作。比如在一个聊天组件中,重新计算聊天内容的高度并调整滚动条位置,以确保新消息能自动显示在可视区域。

ini 复制代码
import { ref, onUpdated } from 'vue';
export default {
  setup() {
    const chatMessages = ref([]);
    onUpdated(() => {
      const chatContainer = document.getElementById('chat - container');
      if (chatContainer) {
        chatContainer.scrollTop = chatContainer.scrollHeight;
      }
    });
    return {
      chatMessages
    };
  }
};

卸载阶段

当组件不再需要时,就会进入卸载阶段。onBeforeUnmount和onUnmounted这两个钩子函数用于处理卸载过程中的清理工作。

onBeforeUnmount在组件卸载之前被调用,此时组件的 DOM 节点仍然存在。我们可以在这里清理定时器、移除事件监听器、取消未完成的网络请求等。例如,一个使用了定时器的组件,在卸载前需要清除定时器,以避免内存泄漏。

javascript 复制代码
import { onBeforeUnmount } from 'vue';
export default {
  setup() {
    let timer;
    const startTimer = () => {
      timer = setInterval(() => {
        console.log('定时器在运行');
      }, 1000);
    };
    onBeforeUnmount(() => {
      if (timer) {
        clearInterval(timer);
        console.log('定时器已移除');
      }
    });
    return {
      startTimer
    };
  }
};

onUnmounted在组件卸载之后被调用,此时 DOM 节点已经从文档中移除。我们可以在这里执行一些最后的清理操作,比如释放一些外部资源。

keep - alive 特有的钩子

在 Vue3 中,当组件被keep - alive包裹时,会涉及到onActivated和onDeactivated这两个特有的钩子函数。

onActivated在被keep - alive缓存的组件重新被激活时触发。这在一些需要保持状态的组件中非常有用,比如一个商品详情页,用户多次进入该页面时,希望保留之前的浏览位置等状态。

javascript 复制代码
import { onActivated } from 'vue';
export default {
  setup() {
    onActivated(() => {
      console.log('组件被激活,恢复之前的状态');
    });
  }
};

onDeactivated在被keep - alive缓存的组件失活时触发。我们可以在这个钩子函数中进行一些状态保存的操作。

javascript 复制代码
import { onDeactivated } from 'vue';
export default {
  setup() {
    onDeactivated(() => {
      console.log('组件失活,保存当前状态');
    });
  }
};

Vue2 与 Vue3 生命周期对比

Vue2 的生命周期和 Vue3 有一些显著的差异。在 Vue2 中,有一个created阶段,而 Vue3 中setup函数可以实现类似的数据初始化和设置功能。

在 Vue2 中,beforeCreate钩子函数在实例化前被调用,此时无法访问组件的数据和方法,适合进行一些初始配置,比如设置一些全局的配置项。

javascript 复制代码
export default {
  beforeCreate() {
    this.$http.defaults.headers.common['Authorization'] = 'Bearer token';
  }
};

created钩子函数在组件实例化后被调用,此时可以访问组件的数据和方法,非常适合进行数据初始化和设置,甚至发起接口请求。由于在这个阶段组件还未挂载到 DOM,所以接口请求的速度相对较快。

javascript 复制代码
export default {
  data() {
    return {
      userData: null
    };
  },
  created() {
    this.$http.get('/api/user')
   .then(response => {
      this.userData = response.data;
    });
  }
};

Vue3 将一些操作推迟到onMounted,这样做的好处是可以规避 SSR(服务器端渲染)的副作用,并保证逻辑在客户端执行。例如,在 Vue3 中,如果我们要使用一些浏览器特有的 API,就需要在onMounted中进行,以确保在服务器端不会出现问题。

父子组件生命周期顺序

理解父子组件的生命周期顺序对于构建复杂的 Vue 应用至关重要。

加载渲染过程

父子组件的加载渲染过程遵循以下顺序:父beforeCreate -> 父create -> 子beforeCreate -> 子Create -> 子mounted -> 父mounted。在这个过程中,父组件首先开始初始化,然后子组件依次进行初始化和挂载,最后父组件完成挂载。

更新过程

当组件数据发生变化时,更新过程的顺序为:父beforeUpdate -> 子beforeupdate -> 子update -> 父update。这个顺序确保了在更新时,父子组件的状态能够正确同步。

销毁过程

当组件需要被销毁时,销毁过程的顺序为:父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed。按照这个顺序,子组件先被清理,然后父组件再进行清理,避免了资源泄漏和内存问题。

Vue 的生命周期是一个强大而复杂的系统,从 Vue2 到 Vue3 的演进中,我们看到了它在不断优化和完善。通过合理利用生命周期钩子函数,我们能够更好地控制组件的行为,构建出更加高效、稳定的前端应用。希望本文能帮助你深入理解 Vue 的生命周期,在实际开发中运用自如。

要是这篇文章能对你有帮助的话,请给作者点个赞吧

相关推荐
前端小白从0开始2 小时前
Vue3项目实现WPS文件预览和内容回填功能
前端·javascript·vue.js·html5·wps·文档回填·文档在线预览
難釋懷3 小时前
Vue解决开发环境 Ajax 跨域问题
前端·vue.js·ajax
挑战者6668883 小时前
vue入门环境搭建及demo运行
前端·javascript·vue.js
程序猿ZhangSir5 小时前
Vue3 项目的基本架构解读
前端·javascript·vue.js
亲亲小宝宝鸭6 小时前
写了两个小需求,终于搞清楚了表格合并
前端·vue.js
Face6 小时前
路由Vue-router 及 异步组件
前端·javascript·vue.js
风之舞_yjf8 小时前
Vue基础(14)_列表过滤、列表排序
前端·javascript·vue.js
疯狂的沙粒8 小时前
uni-app 项目支持 vue 3.0 详解及版本升级方案?
前端·vue.js·uni-app
Lhuu(重开版9 小时前
Vue:Ajax
vue.js·ajax·okhttp
国家不保护废物9 小时前
从刀耕火种到现代框架:DOM编程 vs Vue/React 进化史
前端·vue.js·react.js