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 的生命周期,在实际开发中运用自如。
要是这篇文章能对你有帮助的话,请给作者点个赞吧
