Vue异步更新机制 | $nextTick原理

🌳Vue异步更新机制及$nextTick原理详解

更新周期

更新周期是 Vue.js 用于管理状态变化并更新视图的时间段。Vue.js 使用了一种称为“异步更新队列”的机制来优化性能,它将状态变化的处理推迟到下一个事件循环中执行,从而使得多次状态变化的处理可以被合并成一次更新,提高了性能。

更新周期的划分主要包括以下几个阶段:

  1. 触发状态变化: 更新周期的第一步是触发状态变化。这可能是通过调用 Vue 实例的响应式属性或者通过调用 $set$delete 等方法来修改数据。

  2. 异步更新队列收集: Vue.js 将所有触发的状态变化操作收集到异步更新队列中。在同一个事件循环中,所有的状态变化操作都会被收集起来。

  3. 异步更新队列处理: 在下一个事件循环中,Vue.js 会开始处理异步更新队列。它会遍历队列中的所有状态变化操作,并执行更新操作。

  4. 执行 Virtual DOM 的重新渲染: 对于每个状态变化操作,Vue.js 会重新渲染 Virtual DOM。它会比较前后两个状态下 Virtual DOM 的差异,然后仅仅更新需要更新的部分。

  5. 真实 DOM 的更新: 最后,Vue.js 会将 Virtual DOM 中的变化映射到真实 DOM 上,从而更新页面的显示。

通过这种方式,Vue.js 能够将多次状态变化操作合并成一次更新,减少了更新的次数,提高了性能。同时,这种异步更新机制也能保证所有的状态变化操作在一个更新周期内完成,避免了因多次状态变化而导致的不必要的重复渲染。


组件生命周期图示

生命周期钩子

在 Vue.js 应用程序中,生命周期钩子(Lifecycle Hooks)是一组可以让你在组件的不同生命周期阶段执行自定义代码的函数。这些钩子函数允许你控制组件的创建、更新和销毁过程,以便在不同的时间点执行逻辑代码。

 

Vue.js 的生命周期钩子可以分为以下三个阶段:

  1. 创建阶段(Creation Phase)

    • beforeCreate:在实例被创建之初,数据观测(data observation)和事件/生命周期事件的配置之前调用。
  • created:实例已经完成数据观测、属性和方法的运算,但尚未挂载到 DOM。可以访问数据、进行异步操作等。
  1. 更新阶段(Update Phase)

    • beforeMount:在实例被挂载到 DOM 之前调用。
    • mounted:实例已经挂载到 DOM 上,此时可以访问 DOM 元素,进行操作或与第三方库进行交互。
    • beforeUpdate:在响应式数据更新时,在更新之前调用。
  • updated:在响应式数据更新且 DOM 重新渲染完成后调用。
  1. 销毁阶段(Destruction Phase):

    • beforeUnmount:在实例销毁之前调用。
    • unmounted:实例被销毁后调用,此时组件相关的实例、指令等都被解绑,可进行清理操作。

     

这些生命周期钩子函数可以通过在组件中声明对应名称的方法来使用。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
<div>
<h1>{{ message }}</h1>
<button @click="changeMessage">Change Message</button>
</div>
</template>

<script>
export default {
data() {
return {
message: "Hello, Vue!"
};
},
created() {
console.log("Component created");
},
mounted() {
console.log("Component mounted");
this.startTimer();
},
beforeUpdate() {
console.log("Component before update");
},
updated() {
console.log("Component updated");
},
beforeUnmount() {
console.log("Component before unmount");
this.stopTimer();
},
unmounted() {
console.log("Component unmounted");
},
methods: {
changeMessage() {
this.message = "Message changed!";
},
startTimer() {
this.timer = setInterval(() => {
console.log("Timer tick");
}, 1000);
},
stopTimer() {
clearInterval(this.timer);
}
}
};
</script>

生命周期钩子函数提供了灵活的方式来管理组件的行为,在不同的阶段执行逻辑代码,例如初始化数据、访问 DOM、处理异步操作、清理资源等。它们是 Vue.js 组件开发中非常有用的功能。

 

以下是各个钩子的具体常见用法

  • created 钩子:

    • 初始化数据:可以在 created 钩子中设置组件的默认数据。
    • 发起异步请求:可以在 created 钩子中发起网络请求或获取远程数据。
    • 订阅事件:可以在 created 钩子中订阅全局事件或自定义事件。
  • mounted 钩子:

    • 操作 DOM:可以在 mounted 钩子中获取组件的 DOM 元素,执行 DOM 操作或初始化第三方库。
    • 注册事件监听器:可以在 mounted 钩子中注册事件监听器,以响应用户的交互操作。
    • 开始动画效果:可以在 mounted 钩子中启动动画效果,例如渐变、滚动等。
  • beforeUpdate 钩子:

    • 执行预处理逻辑:可以在 beforeUpdate 钩子中执行数据处理、计算属性等操作,以准备组件的更新。
    • 取消更新:在 beforeUpdate 钩子中检查特定条件,决定是否取消组件的更新。
  • updated 钩子:

    • 执行 DOM 操作:可以在 updated 钩子中执行与 DOM 相关的操作,例如更新 DOM 元素、重绘图表等。
    • 与第三方库交互:可以在 updated 钩子中与其他库进行交互,以响应组件的更新。
  • beforeUnmount 钩子:

    • 清理工作:可以在 beforeUnmount 钩子中取消订阅事件、清除定时器、释放资源等,以准备组件的销毁。
    • 取消网络请求:可以在 beforeUnmount 钩子中取消未完成的网络请求,以避免内存泄漏。