Vue:生命周期钩子

深入理解 Vue 的钩子函数(生命周期函数)

Vue 的钩子函数(生命周期函数)是 Vue 实例在不同阶段自动调用的函数。可以在 Vue 实例的创建、更新、销毁等阶段插入自己的逻辑。


钩子函数的作用

想象一下,Vue 实例的生命周期就像一个人的一生:出生 → 成长 → 衰老 → 死亡。钩子函数就是这些关键阶段的“时间点”。
组件加载时:初始化数据、请求接口数据
DOM 渲染后:操作 DOM 元素
组件销毁前:清除定时器、解绑事件


核心钩子函数详解

创建阶段(Creation)

  • beforeCreate
    触发时机:实例刚被创建,数据观测和事件配置之前。
    能做什么:此时无法访问 datamethods,通常用于插件初始化。
    不能做什么:操作数据或调用方法。

  • created
    触发时机:实例创建完成,数据观测和事件配置已完成。
    能做什么:可以访问 datamethods,适合发起网络请求、初始化数据。
    不能做什么:不要操作 DOM(此时 DOM 还未生成)。

export default {
  data() {
    return { message: "Hello" };
  },
  created() {
    console.log(this.message); // 输出 "Hello"
    this.fetchData(); // 调用方法请求数据
  },
  methods: {
    fetchData() { /* ... */ }
  }
}

2. 挂载阶段(Mounting)

  • beforeMount
    触发时机:模板编译完成,但尚未将 DOM 渲染到页面。
    能做什么:很少使用,一般用于服务端渲染。

  • mounted
    触发时机:DOM 已渲染到页面,可以访问到真实的 DOM 元素。
    能做什么:操作 DOM、使用第三方库(如图表库)。
    确保子组件的 DOM 也已挂载(使用 this.$nextTick 等待)。

mounted() {
  this.$nextTick(() => {
    const element = document.getElementById("my-element");
    element.style.color = "red"; // 操作 DOM
  });
}

3. 更新阶段(Updating)

  • beforeUpdate
    触发时机:数据变化后,DOM 更新前。
    能做什么:获取更新前的 DOM 状态(比如滚动位置)。

  • updated
    触发时机:数据变化导致的 DOM 更新完成后。
    能做什么:执行依赖 DOM 的操作(如重新计算布局)。
    注意:避免在此钩子中修改数据,可能导致无限循环!


4. 销毁阶段(Destruction)

  • beforeDestroy
    触发时机:实例销毁前。
    能做什么:清理定时器、解绑全局事件、取消未完成的请求。

  • destroyed
    触发时机:实例销毁后。
    能做什么:很少使用,用于最后的清理工作。

beforeDestroy() {
  clearInterval(this.timer); // 清除定时器
  window.removeEventListener("resize", this.handleResize); // 解绑事件
}

假设一个组件从创建到销毁的完整流程,钩子函数的执行顺序如下:

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdateupdated
  6. beforeDestroy
  7. destroyed

<template>
  <div class="lifecycle-demo">
    <h2>Vue 生命週期鉤子演示</h2>
    <div class="counter">
      <p>計數器: {{ count }}</p>
      <button @click="increment">增加</button>
    </div>
    <div class="message" v-if="showMessage">
      {{ message }}
    </div>
  </div>
</template>

<script>
export default {
  name: 'LifecycleDemo',
  data() {
    return {
      count: 0,
      message: '',
      showMessage: false
    }
  },
  // 創建實例前
  beforeCreate() {
    console.log('beforeCreate: 實例創建前')
    // 此時 data 和 methods 都還未初始化
  },
  // 創建實例後
  created() {
    console.log('created: 實例創建後')
    // 此時可以訪問 data 和 methods
    this.message = '組件已創建'
  },
  // 掛載前
  beforeMount() {
    console.log('beforeMount: 掛載前')
    // 此時模板已編譯,但還未渲染到 DOM
  },
  // 掛載後
  mounted() {
    console.log('mounted: 掛載後')
    // 此時組件已完全掛載到 DOM
    this.showMessage = true
  },
  // 更新前
  beforeUpdate() {
    console.log('beforeUpdate: 更新前')
    // 數據更新時觸發,但 DOM 還未更新
  },
  // 更新後
  updated() {
    console.log('updated: 更新後')
    // 數據和 DOM 都已更新
  },
  // 銷毀前
  beforeDestroy() {
    console.log('beforeDestroy: 銷毀前')
    // 組件銷毀前,此時組件還可以使用
  },
  // 銷毀後
  destroyed() {
    console.log('destroyed: 銷毀後')
    // 組件已完全銷毀
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

<style scoped>
.lifecycle-demo {
  max-width: 600px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #eee;
  border-radius: 8px;
}

.counter {
  margin: 20px 0;
  padding: 15px;
  background-color: #f5f5f5;
  border-radius: 4px;
}

button {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}

.message {
  margin-top: 10px;
  padding: 10px;
  background-color: #e8f5e9;
  border-radius: 4px;
  color: #2e7d32;
}
</style> 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值