当前位置: 首页 > news >正文

Vue.js 生命周期全面解析

什么是Vue生命周期

Vue生命周期指的是Vue实例从创建到销毁的整个过程中所经历的一系列阶段。在每个阶段,Vue都会提供特定的"钩子函数"(Lifecycle Hooks),允许开发者在不同阶段插入自定义代码,从而实现对Vue实例的精细控制。

理解Vue生命周期对于开发高效、可维护的Vue应用至关重要,它能帮助我们:

  1. 知道在何时执行特定操作(如数据获取、DOM操作等)

  2. 避免在不恰当的阶段执行操作导致的错误

  3. 优化应用性能

  4. 更好地调试和解决问题

Vue生命周期图示

在深入讲解各个生命周期钩子之前,先看一下官方提供的生命周期图示:

开始
│
├── 初始化阶段
│   ├── beforeCreate
│   └── created
│
├── 挂载阶段
│   ├── beforeMount
│   └── mounted
│
├── 更新阶段
│   ├── beforeUpdate
│   └── updated
│
├── 卸载阶段
│   ├── beforeUnmount (Vue 3) / beforeDestroy (Vue 2)
│   └── unmounted (Vue 3) / destroyed (Vue 2)
│
└── 激活阶段 (仅keep-alive组件)├── activated└── deactivated

生命周期钩子详解

1. 初始化阶段

beforeCreate
  • 调用时机:实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用

  • 特点

    • 此时无法访问到data、computed、methods等选项

    • 常用于插件开发中执行一些初始化任务

export default {beforeCreate() {console.log('beforeCreate', this.$data); // undefinedconsole.log('beforeCreate', this.methodName); // undefined}
}
created
  • 调用时机:实例创建完成后被立即调用

  • 特点

    • 可以访问data、computed、methods等

    • 尚未挂载DOM,$el属性不可用

    • 常用于异步数据请求、初始化非响应式属性等

export default {data() {return {message: 'Hello Vue!'}},created() {console.log('created', this.message); // 'Hello Vue!'console.log('created', this.$el); // undefinedthis.fetchData(); // 常见的数据获取操作}
}

2. 挂载阶段

beforeMount
  • 调用时机:在挂载开始之前被调用,相关的render函数首次被调用

  • 特点

    • 模板已编译,但尚未将生成的DOM替换到页面中

    • 很少使用,但在服务端渲染时是唯一可用的钩子

export default {beforeMount() {console.log('beforeMount', this.$el); // 原始的挂载元素}
}
mounted
  • 调用时机:实例被挂载后调用

  • 特点

    • 可以访问到渲染后的DOM

    • 常用于需要操作DOM的库初始化(如图表库)

    • 注意:不保证所有子组件也都一起被挂载

export default {mounted() {console.log('mounted', this.$el); // 渲染后的DOM元素this.initChart(); // 初始化图表库}
}

3. 更新阶段

beforeUpdate
  • 调用时机:数据变化时,虚拟DOM重新渲染和打补丁之前调用

  • 特点

    • 可以在更新前访问现有的DOM状态

    • 适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

export default {beforeUpdate() {console.log('beforeUpdate', this.message);}
}
updated
  • 调用时机:由于数据更改导致的虚拟DOM重新渲染和打补丁后调用

  • 特点

    • 可以执行依赖于DOM的操作

    • 注意:避免在此钩子中更改状态,可能导致无限更新循环

    • 不保证所有子组件也都一起被重绘

export default {updated() {console.log('updated', this.message);// 可以执行DOM相关操作,但要小心无限循环}
}

4. 卸载阶段

beforeUnmount (Vue 3) / beforeDestroy (Vue 2)
  • 调用时机:实例销毁之前调用

  • 特点

    • 实例仍然完全可用

    • 适合执行清理操作,如清除定时器、取消事件监听等

export default {beforeUnmount() { // Vue 3// 或 beforeDestroy() { // Vue 2clearInterval(this.timer);window.removeEventListener('resize', this.handleResize);}
}
unmounted (Vue 3) / destroyed (Vue 2)
  • 调用时机:实例销毁后调用

  • 特点

    • 所有指令都已解绑,所有事件监听器都已移除

    • 所有子实例也都被销毁

export default {unmounted() { // Vue 3// 或 destroyed() { // Vue 2console.log('组件已销毁');}
}

5. 缓存组件相关钩子 (keep-alive)

activated
  • 调用时机:被keep-alive缓存的组件激活时调用

  • 特点

    • 适合执行需要在组件显示时刷新的操作

export default {activated() {this.fetchData(); // 重新获取数据}
}
deactivated
  • 调用时机:被keep-alive缓存的组件失活时调用

  • 特点

    • 适合保存组件状态或清除占用资源的操作

export default {deactivated() {this.saveState(); // 保存组件状态}
}

Vue 2与Vue 3生命周期对比

Vue 2Vue 3说明
beforeCreatebeforeCreate基本相同
createdcreated基本相同
beforeMountbeforeMount基本相同
mountedmounted基本相同
beforeUpdatebeforeUpdate基本相同
updatedupdated基本相同
beforeDestroybeforeUnmount功能相同,名称更语义化
destroyedunmounted功能相同,名称更语义化
-renderTrackedVue 3新增,调试用
-renderTriggeredVue 3新增,调试用
errorCapturederrorCaptured错误捕获,Vue 3有变化

生命周期最佳实践

1、数据获取

  • 使用created或mounted获取初始数据
  • 对于SSR应用,使用created

2、DOM操作

  • 必须在mounted之后进行
  • 避免在updated中进行DOM操作,可能导致无限循环

3、清理工作

  • 在beforeUnmount/beforeDestroy中清除定时器、事件监听等

4、性能优化

  • 避免在频繁触发的钩子(如updated)中执行重操作

5、组件通信

  • 父组件的mounted不保证子组件已挂载,使用$nextTick确保

常见问题与解决方案

1、为什么在created中获取不到DOM元素?

  • 因为此时模板还未编译和挂载,应在mounted中操作DOM

2、mounted不保证所有子组件都挂载怎么办?

  • 使用this.$nextTick确保所有子组件已渲染
mounted() {this.$nextTick(() => {// 这里可以确保所有子组件都已挂载});
}

3、如何在组件销毁前保存状态?

  • 在beforeUnmount/beforeDestroy中保存需要持久化的状态

4、为什么updated中修改数据可能导致无限循环?

  • 因为数据修改会触发更新,更新又会调用updated,形成循环

总结

Vue生命周期是Vue框架的核心概念之一,理解并正确使用各个生命周期钩子能够帮助我们:

  • 在正确的时机执行代码

  • 避免常见错误和性能问题

  • 构建更健壮、可维护的Vue应用

随着Vue 3的推出,生命周期钩子名称更加语义化,并增加了新的调试钩子,但核心概念保持不变。掌握这些知识将为你开发高质量的Vue应用奠定坚实基础。

相关文章:

  • 宁乡地-气-碳-水相互作用综合观测数据集
  • 香港科技大学(广州) | 生命科学与生物医学工程学域博士夏令营报名召集!
  • 基于JWT+SpringSecurity整合一个单点认证授权机制
  • 在UI界面内修改了对象名,在#include “ui_mainwindow.h“没更新
  • 探索Python融合地学:斗之气三段
  • 深度解构Vue3响应式内核:Proxy魔法与依赖追踪的极致艺术
  • 1.4 编译库:静态库、动态库
  • Java并发容器和原子类
  • caliper中的测试文件写法及其注意事项
  • 谷歌云代理商 | 游戏行业专属方案:谷歌云实时多人游戏服务器架构
  • 在Windows下利用LoongArch-toolchain交叉编译Qt
  • C++编程——关于比较器的使用
  • 五子棋网络对战游戏的设计与实现设计与实现【源码+文档】
  • 常见工具导出DDL语句
  • 图片切割工具:智能分割长图并控制文件大小
  • 三维GIS开发cesium智慧地铁教程(4)城市白模加载与样式控制
  • 数据任务调度解决离不开离线开发BatchWorks
  • 单周期cpu和多周期cpu、单周期数据通路和多周期数据通路与总线结构数据通路和专用数据通路的关系
  • AOP实现Restful接口操作日志入表方案
  • CC7利用链深度解析
  • 哪里能找到免费网站/百度小说排行榜前十名
  • h5响应式网站建设方案/南宁百度seo排名优化
  • 建筑网站汇总/搜狗推广登录
  • 网站建设前景/抖音广告代运营
  • 刷单做任务的网站/新出的app推广在哪找
  • 营销型企业网站包括哪些类型/关键词搜索方法