在 Vue.js 开发中,理解组件的生命周期是构建健壮应用程序的关键。虽然 Vue3 引入了 Composition API,但 Options API 仍然是许多开发者的首选,特别是对于从 Vue2 迁移的项目或更喜欢基于选项的代码组织的团队。本文将深入探讨 Vue3 中 Options API 的生命周期函数,帮助您掌握组件从创建到销毁的完整过程。

1. 生命周期概览

Vue3 的生命周期与 Vue2 相比有一些变化,主要是为了更好的支持 Composition API 并优化性能。以下是完整的生命周期图示:

setup (Composition API 特有)
|
└── beforeCreate└── created└── beforeMount└── mounted├── beforeUpdate│   └── updated├── activated (keep-alive 组件特有)│   └── deactivated (keep-alive 组件特有)└── beforeUnmount└── unmounted

2. 各生命周期钩子详解

2.1 beforeCreate

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

典型用途

  • 执行一些不依赖响应式数据的初始化逻辑
  • 设置一些实例属性,这些属性可能在后续的 created 钩子中使用
export default {beforeCreate() {console.log('beforeCreate: 实例刚创建,数据观测未初始化');console.log(this.$data); // undefinedconsole.log(this.someData); // undefined},data() {return {someData: 'Hello'}}
}

2.2 created

触发时机:在实例创建完成后被立即调用。在这一步,实例已完成以下配置:

  • 数据观测 (data observer)
  • 属性和方法的运算
  • watch/event 事件回调

典型用途

  • 访问响应式数据
  • 发起异步请求获取数据
  • 初始化一些需要响应式数据的逻辑
export default {data() {return {message: 'Hello Vue!'}},created() {console.log('created: 实例已创建,数据观测已初始化');console.log(this.message); // 'Hello Vue!'// 发起API请求this.fetchData();},methods: {fetchData() {// 异步数据获取逻辑}}
}

2.3 beforeMount

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

典型用途

  • 在组件挂载到DOM之前执行最后的准备工作
  • 很少需要在此钩子中进行操作,大多数情况下使用 created 或 mounted 更合适
export default {beforeMount() {console.log('beforeMount: 模板编译完成,即将挂载到DOM');console.log(this.$el); // undefined,尚未挂载}
}

2.4 mounted

触发时机:实例被挂载后调用,这时 el 被新创建的 vm.$el 替换。

典型用途

  • 访问或操作DOM元素
  • 集成第三方库需要DOM存在的场景
  • 执行依赖于DOM的初始化操作
export default {mounted() {console.log('mounted: 实例已挂载到DOM');console.log(this.$el); // 可以访问DOM元素// 使用第三方图表库this.initChart();},methods: {initChart() {const ctx = this.$refs.chartCanvas.getContext('2d');// 初始化图表...}}
}

2.5 beforeUpdate

触发时机:数据更新时调用,发生在虚拟 DOM 打补丁之前。

典型用途

  • 在组件更新前访问现有的DOM状态
  • 跟踪组件更新前的状态
export default {data() {return {counter: 0}},beforeUpdate() {console.log('beforeUpdate: 数据即将更新');console.log('当前值:', this.$refs.counter.textContent);}
}

2.6 updated

触发时机:由于数据更改导致的虚拟 DOM 重新渲染和打补丁后调用。

典型用途

  • 执行依赖于DOM更新的操作
  • 谨慎使用,避免在此钩子中修改状态,可能导致无限更新循环
export default {data() {return {items: []}},updated() {console.log('updated: DOM已更新');// 在列表更新后滚动到底部this.$refs.list.scrollTop = this.$refs.list.scrollHeight;}
}

2.7 beforeUnmount (Vue2中的beforeDestroy)

触发时机:实例销毁之前调用。在这一步,实例仍然完全可用。

典型用途

  • 清理定时器
  • 取消事件监听
  • 清理第三方库的实例
export default {data() {return {timer: null}},created() {this.timer = setInterval(() => {console.log('Timer tick');}, 1000);},beforeUnmount() {console.log('beforeUnmount: 实例即将销毁');clearInterval(this.timer);}
}

2.8 unmounted (Vue2中的destroyed)

触发时机:实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

典型用途

  • 执行最后的清理工作
  • 报告分析数据或日志
export default {unmounted() {console.log('unmounted: 实例已销毁');// 发送日志this.sendAnalytics('Component destroyed');}
}

2.9 activated 和 deactivated (keep-alive 特有)

触发时机

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

典型用途

  • 恢复或暂停组件特定的行为
  • 获取最新数据(activated)
  • 保存组件状态(deactivated)
export default {activated() {console.log('activated: 组件被激活');// 获取最新数据this.fetchData();},deactivated() {console.log('deactivated: 组件被缓存');// 保存滚动位置this.scrollPosition = this.$refs.list.scrollTop;}
}

3. Vue2 到 Vue3 的生命周期变化

  1. 重命名:

    • beforeDestroybeforeUnmount
    • destroyedunmounted
  2. 新增:

    • renderTrackedrenderTriggered(主要用于调试)
  3. 行为变化:

    • 生命周期钩子现在都使用异步队列执行,确保一致性

4. 最佳实践

  1. 数据获取:通常在 created 钩子中进行异步数据获取,这样可以在组件挂载前尽早开始请求。

  2. DOM操作:必须在 mounted 钩子中进行,因为只有这时DOM才存在。

  3. 清理工作:在 beforeUnmount 中清理定时器、事件监听器等,防止内存泄漏。

  4. 避免在 updated 中修改状态:这可能导致无限更新循环。

  5. keep-alive 组件优化:使用 activateddeactivated 来管理缓存组件的状态。

  6. 代码组织:将相关生命周期逻辑分组注释,提高代码可读性。

export default {// 数据相关data() { /* ... */ },created() { /* 数据初始化 */ },// DOM相关mounted() { /* DOM操作 */ },beforeUnmount() { /* 清理DOM相关资源 */ },// 状态更新相关beforeUpdate() { /* 更新前操作 */ },updated() { /* 更新后操作 */ },// keep-alive相关activated() { /* 恢复状态 */ },deactivated() { /* 保存状态 */ }
}

5. 常见问题解答

Q: created 和 mounted 哪个更适合发起API请求?

A: 通常建议在 created 中发起API请求,这样可以尽早开始数据获取,减少用户等待时间。只有在请求结果直接影响DOM时才需要在 mounted 中发起请求。

Q: 为什么我的 beforeUpdate 钩子没有被触发?

A: beforeUpdate 只在响应式数据变化导致重新渲染时触发。如果您的数据变化不影响模板,或者使用了非响应式数据,钩子不会被调用。

Q: Vue3 中是否可以混用 Options API 和 Composition API 的生命周期?

A: 可以,但不推荐。Composition API 使用 setup() 函数中的生命周期钩子(如 onMounted),而 Options API 使用我们讨论的这些钩子。混用可能导致逻辑分散,降低代码可读性。

6. 结语

理解 Vue3 的 Options API 生命周期钩子是构建高效、可维护 Vue 应用程序的基础。通过合理利用这些钩子,您可以精确控制组件的行为,优化性能,并避免常见问题。随着对生命周期的深入理解,您将能够编写出更加健壮和可预测的 Vue 组件。

记住,虽然生命周期钩子提供了强大的控制能力,但过度使用它们可能导致代码难以维护。始终考虑是否有更简单的方式来实现您的需求,例如使用计算属性或侦听器来代替某些生命周期逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90141.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90141.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/90141.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周志华《机器学习导论》第8章 集成学习 Ensemble Learning

目录 8.1 个体与集成 8.2 Boosting Ada(Adaptive)Boost 8.3 Bagging 8.4 随机森林 8.5 结合策略 8.5.1 平均法 8.5.2 投票法 8.5.3 学习法 8.6 多样性 8.6.1 误差-分歧分解 error-ambiguity 8.6.2 多样性度量 8.6.3 多样性增强 8.1 个体与集…

Embassy实战:Rust嵌入式异步开发指南

嵌入式异步框架 Embassy 实例 以下是关于嵌入式异步框架 Embassy 的实用示例,涵盖常见外设操作、多任务协作和硬件交互场景。示例基于STM32和Raspberry Pi Pico等平台,使用Rust语言编写。 GPIO 控制 use embassy_stm32::gpio::{Input, Output, Pull, Speed}; use embassy_…

ChatGPT桌面版深度解析

ChatGPT桌面版深度解析:功能、安装与高效使用全攻略 一、核心功能全景解析 (一)全场景交互体系 全局热键唤醒 支持MacOS(Option空格)与Windows(Alt空格)全局快捷键,实现跨应用无缝调…

RLVR的一种扩展方案--RLPR论文阅读

论文链接:RLPR: EXTRAPOLATING RLVR TO GENERAL DOMAINS WITHOUT VERIFIERS 文章目录简介RLPRRLVR概率奖励/Probability Reward奖励设计标准差过滤总结简介 可验证奖励的强化学习(Reinforcement Learning with Verifiable Rewards, RLVR)在提升大语言模型&#xff…

odoo欧度小程序——添加用户

odoo欧度小程序添加登录用户 1. 直接在登录用户页面添加用户点击 添加登录用户输入用户和密码,点击登录验证进入odoo页面2. 在用户切换页面添加用户点击选择切换用户点击域名弹出菜单点击添加新用户输入用户和密码,点击登录验证进入odoo页面

Docker 应用数据备份、迁移方案

一、为什么要做Docker数据备份1、保障数据与配置的安全性防止数据丢失:Docker 容器本身是 “临时性” 的(基于镜像创建,删除后数据默认丢失),但容器中运行的应用(如数据库、日志服务)会产生持久…

【PTA数据结构 | C语言版】强连通分量

本专栏持续输出数据结构题目集,欢迎订阅。 文章目录题目代码题目 本题请你编写程序,输出给定有向图中的各个强连通分量,并统计强连通分量的个数。 输入格式: 输入首先在第一行给出 2 个整数,依次为有向图的顶点数 n&…

idea部署新项目时,用自定义的maven出现的问题解决

出现这个问题是因为maven版本和idea版本不兼容,例如图示是maven3.9和idea2021.3的版本不兼容,maven换成3.8.x即可解决

OCR 身份识别:让身份信息录入场景更高效安全

在银行柜台开户、线上平台实名认证等场景中,身份信息录入是基础环节,OCR 身份识别产品正成为提升效率与安全性的关键。​传统人工录入身份证信息,不仅耗时久,还易因手误导致姓名、号码出错,影响业务办理进度。而 OCR 身…

Web 服务器和Web 中间件

一、什么是 Web 中间件 Web 中间件(Web Middleware)是运行在 Web 服务器与实际业务程序之间的一层“胶水”软件,用来统一处理公共事务,让开发者专注写业务逻辑。常见职责: 请求/响应拦截(鉴权、日志、跨域、…

Paimon的部分更新以及DeleteVector实现

背景 本文基于 Paimon 0.9 出于对与Paimon内部的DeleteVctor的实现以及部分更新的实现进行的源码阅读。 关于 DeleteVector的介绍可以看这里 说明 对于Paimon来说无论是Spark中使用还是Flink使用,后面的逻辑都是一样的,所以我们以Spark为例来说。所以…

Redis 的事务机制是怎样的?

Redis 的事务机制 Redis支持事务机制,其主要目的是确保多个命令执行的原子性,即这些命令会作为一个不可分割的操作单元执行。 需要注意的是,Redis事务不支持回滚操作。从Redis 2.6.5版本开始,服务器会在命令累积阶段检测错误。在执行EXEC命令时,若发现错误则会拒绝执行事…

网安学习NO.17

1. VPN 概述定义:在公用网络(如 Internet、帧中继、ATM 等)中,通过技术手段虚拟出的一条企业内部专线,能像私有网络一样提供安全性、可靠性和可管理性。核心特征:利用公共网络构建,具备 “虚拟性…

MCU芯片AS32S601在卫星光纤放大器(EDFA)中的应用探索

摘要:本文聚焦于国科安芯推出的AS32S601型MCU芯片在卫星光纤放大器(EDFA)中的潜在应用,探讨其技术特性、抗辐射性能及适用性。通过分析其在单粒子效应脉冲激光试验中的表现,结合EDFA系统对控制芯片的要求,评…

Hexo - 免费搭建个人博客02 - 创建个人博客

导言我的博客:https://q164129345.github.io/ 开始一步一步地完成博客的创建。 一、初始化Hexo博客以上所示,运行以下指令在myCode文件夹里初始化一个hexo博客。 hexo init myblog二、安装依赖如上所示,完成依赖的安装。 cd myblog npm insta…

单片机-----基础知识整合

一、基础知识1)单片机的组成:中央处理器CPU、随机存储器RAM、只读存储器ROM、定时器、多种I/O接口、中断系统等2)STM32U575RIT6采用ARM Cortex-M33内核架构ARM是什么?①ARM是一家公司,ARM公司是一家芯片知识产权&#…

双流join 、 Paimon Partial Update 和 动态schema

背景 Paimon 通过其独特的 partial-update 合并引擎和底层的 LSM 存储结构,巧妙地将传统双流 Join 中对 Flink State 的高频随机读/写,转换为了对 Paimon 表的顺序写和后台的高效合并,从而一站式地解决了 Flink 作业状态过大、依赖外部 KV 系…

7.3.1 进程调度机制那些事儿

一:task_struct结构体分析 1、进程有两种特殊形式:没有用户虚拟地址空间的进程叫内核线程,共享用户虚拟地址空间的进程叫作用户线程。共享同一个用户虚拟地址空间的所有用户线程叫线程组。 C语言标准库进程 Linux内核进程 …

基于多种机器学习的水质污染及安全预测分析系统的设计与实现【随机森林、XGBoost、LightGBM、SMOTE、贝叶斯优化】

文章目录有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍总结每文一语有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 随着工业化和城市化的不断推进,水质污染问题逐渐成为影响生态环境…

Linux第三天Linux基础命令(二)

1.grep命令可以通过grep命令,从文件中通过关键字过滤文件行。grep [-n] 关键字 文件路径选项-n,可选,表示在结果中显示匹配的行的行号。参数,关键字,必填,表示过滤的关键字,带有空格或其它特殊符…