Vue 实例生命周期

一、什么是生命周期?

Vue 实例从创建销毁 的整个过程,称为生命周期。

在这个过程中,Vue 会在特定阶段自动调用一些函数,这些函数就是生命周期钩子(Lifecycle Hooks)

你可以把它们理解为"生命阶段的回调函数",在合适的时机执行特定逻辑。

二、Vue 2 生命周期图谱(经典八阶段)

以下是 Vue 2 的生命周期流程图(建议配图):

复制代码
beforeCreate
     ↓
   created  ←←←←← (可发起请求)
     ↓
 beforeMount
     ↓
   mounted  ←←←←← (DOM 可访问,常用)
     ↓
 beforeUpdate
     ↓
   updated
     ↓
 beforeDestroy
     ↓
  destroyed

红色箭头 表示组件可能被销毁后重新创建(如 v-if 切换)。


1. beforeCreate

  • 触发时机:实例初始化之后,数据观测 (data observer) 和事件配置之前。
  • 能做什么 :几乎不能做任何事,datamethods 还未初始化。
  • 使用场景:极少使用。
javascript 复制代码
beforeCreate() {
  console.log('beforeCreate: ', this.message) // undefined
}

2. created

  • 触发时机:实例创建完成,数据观测、属性和方法运算已完成。
  • 能做什么
    • 访问 datamethods
    • 发起 Ajax 请求
    • 设置定时器(注意清理)
  • 不能做什么 :访问 DOM($elundefined
javascript 复制代码
created() {
  console.log('created: ', this.message) // 正常输出
  this.fetchData() // ✅ 推荐在此发起请求
}

最佳实践:数据初始化、异步请求。


3. beforeMount

  • 触发时机:模板编译完成,但尚未挂载到 DOM。
  • 能做什么 :很少使用,此时 $el 仍不可用。
  • 注意:服务端渲染(SSR)不会调用此钩子。
javascript 复制代码
beforeMount() {
  console.log('beforeMount: ', this.$el) // undefined
}

4. mounted

  • 触发时机 :实例挂载到 DOM 后,$el 被新创建的 vm.$el 替换。
  • 能做什么
    • 操作 DOM(如初始化第三方库:Swiper、ECharts)
    • 访问 $refs
    • 开始定时器
  • 重要 :组件已"可见",是最常用的钩子之一。
javascript 复制代码
mounted() {
  console.log('mounted: ', this.$el) // 可访问 DOM
  this.initChart() // 初始化图表
  this.timer = setInterval(() => {
    // 轮询
  }, 5000)
}

最佳实践:DOM 操作、第三方库初始化、定时器启动。


5. beforeUpdate

  • 触发时机:数据更新时,虚拟 DOM 重新渲染之前。
  • 能做什么:获取更新前的 DOM 状态。
  • 注意:不要在此修改状态,否则可能造成无限循环。
javascript 复制代码
beforeUpdate() {
  console.log('视图更新前,数据是:', this.message)
}

6. updated

  • 触发时机:数据更新后,虚拟 DOM 重新渲染并应用到 DOM。
  • 能做什么
    • DOM 操作(依赖更新后的 DOM)
    • 避免在此发起状态更新,可能造成循环
  • 注意:子组件可能尚未更新。
javascript 复制代码
updated() {
  console.log('视图已更新')
  // 可操作更新后的 DOM
}

⚠️ 避免updated 中修改 data,否则会再次触发更新。


7. beforeDestroy(Vue 2)/ beforeUnmount(Vue 3)

  • 触发时机:实例销毁前,实例仍完全可用。
  • 能做什么
    • 清理定时器
    • 移除事件监听
    • 解除第三方库绑定
  • 必须做:防止内存泄漏!
javascript 复制代码
beforeDestroy() {
  clearInterval(this.timer)
  window.removeEventListener('resize', this.onResize)
  this.$refs.chart.dispose() // 如 ECharts
}

最佳实践:资源清理,必做!


8. destroyed(Vue 2)/ unmounted(Vue 3)

  • 触发时机:实例销毁后,所有绑定和监听器被移除。
  • 能做什么:很少使用,实例已不可用。
javascript 复制代码
destroyed() {
  console.log('组件已销毁')
}

三、Vue 3 生命周期的变化

Vue 3 中,部分生命周期钩子名称更新,以与 Composition API 保持一致:

Vue 2 Vue 3
beforeDestroy beforeUnmount
destroyed unmounted

📌 其他钩子名称不变

Composition API 中的生命周期钩子

setup() 中,使用 onXxx 函数注册生命周期钩子:

html 复制代码
<script>
import { 
  onMounted, 
  onUpdated, 
  onUnmounted 
} from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('组件已挂载')
    })

    onUpdated(() => {
      console.log('组件已更新')
    })

    onUnmounted(() => {
      console.log('组件已卸载')
      // 清理资源
    })

    return {}
  }
}
</script>

✅ 所有 onXxx 函数必须在 setup()<script setup> 中调用。

四、生命周期实战应用场景

1. 发起 API 请求

javascript 复制代码
created() {
  this.loading = true
  fetch('/api/users')
    .then(res => res.json())
    .then(data => {
      this.users = data
    })
    .finally(() => {
      this.loading = false
    })
}

created 是发起请求的最佳时机。


2. 初始化第三方库

javascript 复制代码
mounted() {
  this.chart = new Chart(this.$refs.canvas, {
    type: 'bar',
    data: this.chartData
  })
}

3. 清理资源(防内存泄漏)

javascript 复制代码
export default {
  data() {
    return {
      timer: null
    }
  },
  mounted() {
    this.timer = setInterval(() => {
      this.updateTime()
    }, 1000)
  },
  beforeUnmount() {
    if (this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }
  }
}

✅ 必须在 beforeUnmount 中清理!


4. 监听窗口事件

javascript 复制代码
mounted() {
  window.addEventListener('resize', this.handleResize)
},
beforeUnmount() {
  window.removeEventListener('resize', this.handleResize)
}

五、常见问题与注意事项

createdmounted 有什么区别?

阶段 能访问数据 能访问 DOM
created
mounted

数据请求放 created,DOM 操作放 mounted


❓ 为什么不能在 beforeCreate 中访问 data

因为此时 Vue 还未完成数据观测(Observer)的初始化。


updated 会频繁触发吗?

会!每次数据更新 都会触发 updated,避免在此执行昂贵操作。


❓ 子组件的生命周期顺序?

父组件 beforeCreatecreatedbeforeMount

子组件 beforeCreatecreatedmounted

父组件 mounted

先子后父

六、总结:生命周期钩子使用指南

钩子 是否常用 典型用途
created 数据初始化、API 请求
mounted DOM 操作、第三方库初始化
beforeUpdate ⚠️ 获取更新前状态
updated ⚠️ 依赖更新后 DOM 的操作
beforeUnmount 清理定时器、事件监听
unmounted ⚠️ 组件销毁后通知

📌 核心原则:在合适的时机做合适的事。

七、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
JNU freshman3 小时前
vue 之 import 的语法
前端·javascript·vue.js
剑亦未配妥3 小时前
Vue 2 响应式系统常见问题与解决方案(包含_demo以下划线开头命名的变量导致响应式丢失问题)
前端·javascript·vue.js
爱吃的强哥3 小时前
Vue2 封装二维码弹窗组件
javascript·vue.js
凉柚ˇ3 小时前
Vue图片压缩方案
前端·javascript·vue.js
慧一居士3 小时前
vue 中 directive 作用,使用场景和使用示例
前端
慧一居士3 小时前
vue 中 file-saver 功能介绍,使用场景,使用示例
前端
优弧3 小时前
Vue 和 React 框架对比分析:优缺点与使用场景
vue.js
文心快码BaiduComate4 小时前
文心快码3.5S实测插件开发,Architect模式令人惊艳
前端·后端·架构