Vue2 生命周期钩子详解:beforeCreate、created、mounted、beforeDestroy 用法顺序与坑点指南
1. 创建阶段(Create)
1.1. beforeCreate(创建前)
此时 Vue 刚被 new
出来,但是内部的数据监听(data)和事件系统(events)都还没有被初始化。
不能访问 data
、computed
、methods
,因为它们还不存在,访问会得到 undefined
。
能做一些与实例本身无关的事情,比如添加一个全局的事件监听,或者在Vue实例上挂载一些不需要响应式的数据。但这个钩子用得非常少。(做一些插件初始化、原始数据准备)
1.2. create(创建后)
Vue 实例已经完成了数据监听 data
、计算属性 computed
、方法 methods
、侦听器 watch
的初始化。但是 DOM 还没有挂载。
不能操作 DOM,因为此时还没有真实的 DOM 元素被挂载到页面上。如果访问 document.getElementById(...)
,会得到 null
。
能访问并且修改 data
、computed
、methods
、watch
,并且是响应式的。
2. 挂载阶段(Mounting)
2.1. beforMount(挂载前)
Vue 已经根据模板(template)在内存中创建好了虚拟DOM(Virtual DOM),但还没有把它转换成真实的DOM并挂载到页面上。
不能操作 DOM,真实 DOM 还未渲染,el
所指向的DOM元素(比如 <div id="app"></div>
)还是一个空的“壳子”。
能访问并且修改 data
、computed
、methods
、watch
,并且是响应式的。
2.2. mounted(挂载后)
Vue 已经将内存的虚拟 DOM 渲染成了真实 DOM,并替换了 el
选项所指向的元素。组件已经完全显示在页面上了。
可以操作 DOM,可以使用 document.getElementById
,或者通过 this.$refs
访问子组件或DOM元素。可以初始化第三方库,比如 ECharts、Sortable.js 等,因为它们都需要一个已存在的DOM容器。可以发起需要依赖DOM的异步请求。
注意:虽然 mounted
保证了 DOM 已经存在,但不保证DOM的所有子组件都已挂载完成。如果你需要确保所有子组件也都准备好了,应该使用 this.$nextTick()
。
3. 更新阶段
3.1. beforeUpdate(更新前)
当组件 data
发生改变时,这个钩子会被触发,此时数据已经是最新的了,但屏幕上的 DOM 还是旧的。
可以获取更新前的 DOM 状态。
不可以在这里修改数据,否则会触发无限循环更新!
3.2. updated(更新后)
Vue 已经根据最新的数据完成了虚拟 DOM 的重新渲染和打补丁(patch),屏幕上的 DOM 也已经是最新的状态了。
可以操作更新后的 DOM。
与 beforeUpdate
一样,绝对不要在这里修改数据,否则会导致无限循环。如果需要根据 DOM 状态的变化来修改数据,应该使用 `watch` 或 computed
。
4. 销毁阶段
4.1. beforeDestory(销毁前)
Vue 的实例仍然可以使用。
可以访问 DOM、data、computed、methods。
常用来做 清理操作(比如 clearInterval
、移除事件监听)。
4.2. destoryed(销毁后)
Vue 实例完全被销毁。它与 DOM 的绑定被解除,所有的事件监听被移除,所有的子实例也被销毁。
依然能访问 data、methods(只是不会再触发响应式更新)
真实 DOM 已经被移除,不能再操作 DOM。