1.7vue声明周期
生命周期阶段与钩子函数
创建阶段
beforeCreate()
:实例初始化之后,数据观测和事件配置之前调用。此时无法访问到data
、methods
等属性。created()
:实例创建完成后调用。完成了数据观测,属性和方法的运算,watch/event事件回调。但是尚未挂载到DOM。
挂载阶段
beforeMount()
:模板编译完成,即将挂载到DOM前调用。此时页面呈现的是未经Vue编译的DOM结构。mounted()
:组件挂载到DOM后调用。可以操作真实DOM。
更新阶段
beforeUpdate()
:数据更新时,虚拟DOM重新渲染前调用。可以在这里进行状态记录或取消更新。updated()
:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用。此时可以对更新后的DOM进行操作。
销毁阶段
beforeDestroy()
:实例销毁之前调用。在这一步,实例仍然完全可用。通常用来清理定时器、解除绑定等。destroyed()
:实例销毁后调用。调用后,所有的事件监听器和所有子实例都会被移除。
钩子函数的应用场景
- 在
created
中发送异步请求获取数据。 - 在
mounted
中操作DOM元素或者初始化第三方库。 - 在
beforeUpdate
中可以获取当前的状态并在必要时进行修改,但要小心避免造成无限循环更新。 - 在
beforeDestroy
中释放资源,比如清除定时器或者解绑事件监听器。
Vue.nextTick
Vue.nextTick()
是一个非常重要的工具,用于在下次 DOM 更新循环结束之后执行回调函数。当你修改了数据,但需要在 DOM 实际更新后进行某些操作时,就需要使用 nextTick
。
典型使用场景示例:获取更新后的 DOM 元素尺寸
假设你有一个按钮,点击后切换一个 div 的显示状态(v-show
),并希望在 div 显示出来后立即获取它的高度。
错误做法(不使用 nextTick)
<template><div><button @click="showDiv">显示 div 并获取高度</button><div v-show="isVisible" ref="myDiv" style="background: lightblue;">这是一个动态显示的 div,内容可能很多...</div></div>
</template><script>
export default {data() {return {isVisible: false}},methods: {showDiv() {this.isVisible = true; // 数据更新,触发 DOM 更新// ❌ 错误:此时 DOM 还没有更新!const divHeight = this.$refs.myDiv.offsetHeight;console.log('高度:', divHeight); // 可能输出 0 或旧值}}
}
</script>
在这个例子中,this.isVisible = true
触发了 DOM 更新,但 Vue 的更新是异步批量处理的。当你立即访问 this.$refs.myDiv.offsetHeight
时,DOM 还没有完成渲染,因此你可能获取不到正确的高度。
正确做法(使用 nextTick)
<template><div><button @click="showDiv">显示 div 并获取高度</button><div v-show="isVisible" ref="myDiv" style="background: lightblue;">这是一个动态显示的 div,内容可能很多...</div></div>
</template><script>
export default {data() {return {isVisible: false}},methods: {showDiv() {this.isVisible = true; // 数据更新// ✅ 正确:在 DOM 更新完成后执行this.$nextTick(() => {const divHeight = this.$refs.myDiv.offsetHeight;console.log('真实高度:', divHeight); // 输出正确的高度// 你可以在这里进行基于 DOM 尺寸的后续操作});}}
}
</script>
为什么需要 nextTick
?
- Vue 在检测到数据变化后,不会立即更新 DOM,而是开启一个队列,异步地批量更新。
- 这样可以避免在同一个事件循环中多次状态变更导致的重复渲染,提高性能。
nextTick
回调会在 Vue 刷新 DOM 后执行,确保你能访问到最新的 DOM 状态。