Vue生命周期那些事儿 - 为什么我总在mounted里发请求?

大家好,我是小杨,一个干了6年前端的老油条。今天想和大家聊聊Vue生命周期里那些"约定俗成"的做法背后的原因,特别是为什么我们总在mounted里发网络请求这个话题。

记得我刚学Vue那会儿,看到生命周期钩子函数一堆,什么created、mounted傻傻分不清楚,最懵的就是:"为啥前辈们的代码都在mounted里写axios请求?created不是更早执行吗?早点发请求不是更好吗?" 今天我就用最直白的话给大家讲明白。

一、Vue生命周期快速导览

先上个我手绘的流程图(脑补一下),Vue实例的生命周期大概是这样:

text 复制代码
开始 → beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeDestroy → destroyed

用大白话说就是:

  1. 出生阶段(创建)
  2. 挂载阶段(上树)
  3. 成长阶段(更新)
  4. 凉凉阶段(销毁)

二、为什么是mounted?

重点来了!为什么网络请求推荐放在mounted而不是created?这里有个关键点:

javascript 复制代码
export default {
  async created() {
    // 我在这里发请求会怎样?
    const res = await axios.get('/api/data')
    this.data = res.data
    // 危险操作!
    document.querySelector('#myDiv').innerHTML = '提前操作DOM可能会翻车'
  },
  mounted() {
    // 这里才是安全的操作区
    console.log(document.querySelector('#myDiv')) // 保证能拿到元素
  }
}

三个核心原因:

  1. DOM是否就绪:created时模板还没编译成真实的DOM,mounted时才真正挂载完成。就像装修房子,created时刚买好建材,mounted时才算装修完能住人。
  2. SSR兼容性:如果是服务端渲染(SSR),created会在服务端执行,而mounted只会在客户端执行。把有副作用的操作(比如访问window对象)放mounted能避免报错。
  3. 用户体验:虽然created更早发请求,但实际差距只有几毫秒,用户根本感知不到区别。相比之下,确保DOM就绪更重要。

三、我的翻车现场

刚入行时我写过这样的代码:

javascript 复制代码
created() {
  fetchData().then(data => {
    this.list = data
    // 这里想立即操作DOM
    this.$refs.listContainer.scrollTo(0, 100) // 报错!$refs还没挂载
  })
}

结果当然是页面炸了,$refs根本拿不到元素。后来才明白,这就好比孩子还没出生(DOM没挂载)就想给他穿衣服,能不报错吗?

四、特殊情况怎么办?

当然也有例外情况:

  • 如果你不需要操作DOM,只是获取数据,created也可以
  • 使用keep-alive时,可以用activated钩子
  • 对于SSR项目,可能要在created里预取数据

但记住一个黄金法则:只要涉及DOM操作,请老老实实放mounted里!

五、最佳实践建议

经过多年踩坑,我的建议是:

  1. 默认放mounted
  2. 在组件created时初始化数据
  3. 需要操作DOM的方法都写在mounted之后
  4. 清理操作(如定时器)放beforeDestroy
javascript 复制代码
export default {
  data() {
    return {
      loading: false,
      list: []
    }
  },
  async mounted() {
    this.loading = true
    try {
      this.list = await fetchData()
      // 这里可以安全操作DOM
      this.$nextTick(() => {
        this.$refs.container.scrollTop = 0
      })
    } finally {
      this.loading = false
    }
  }
}

六、总结

Vue的生命周期就像人的一生,每个阶段都有适合做的事情。在正确的时间做正确的事,代码才会更健壮。下次当你准备写网络请求时,不妨想想小杨的忠告:除非有特殊需求,否则mounted永远是你的好朋友!

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
人工智能训练4 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪5 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9226 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233226 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88218 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1368 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠8 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
2601_949833398 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
珑墨8 小时前
【Turbo】使用介绍
前端
军军君019 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three