vue2生命周期
# vue2.0 生命周期
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
# 生命周期钩子函数
beforeCreate:组件刚被创建,组件属性计算之前
created:组件实例创建完成,属性已绑定, 但真实 dom 还没有生成,$el 还不可用,但是 data 和 method 可用
beforeMount:此时已经完成了模板的编译,在页面挂载开始之前被调用, 相关的 render 函数首次被调用
mounted:已经将编译好的模板,挂载到了页面指定的容器中显示,可操作 DOM(最早)
beforeUpdate:状态更新之前执行此函数,此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,此时还没有开始重新渲染 DOM 节点
updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
beforeDestroy:实例销毁之前调用。在这一步,实例(data,methods,过滤器,指令)仍然完全可用。
使用场景:(日期在我点击查询的时候要存储,刷新就读内存,但是我点击其他页面再进来的时候,这个内存要清空)
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
activited keep-alive 专属,组件被激活时调用
deactivated keep-alive 专属,组件被销毁时调用
# 第一次加载会触发哪些钩子函数
beforeCreate, created, beforeMount, mounted
# 在哪个钩子函数中调用接口
可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。但是本人推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:
能更快获取到服务端数据,减少页面 loading 时间;
ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;
问题:在 beforeCreated 中发出请求合适吗?会出现什么问题?
不合适,beforeCreated 生命周期触发时,这个时候 data 和 method 都还没初始化好,是不能直接调用 method 和 data 的
调用方法会报错,使用 data 会 undefined
# 在什么阶段才能访问操作 DOM?
在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。
需要注意的是,在 created 和 mounted 阶段,如果需要操作渲染后的试图,也要使用 nextTick 方法。
注意:mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick
vue 具体的生命周期示意图可以参见如下,理解了整个生命周期各个阶段的操作,关于生命周期相关的面试题就难不倒你了。
# 父组件可以监听到子组件的生命周期吗?
比如有父组件 Parent 和子组件 Child,如果父组件监听到子组件挂载 mounted 就做一些逻辑处理,可以通过以下写法实现:
// Parent.vue
<
Child @mounted = "doSomething" / >
// Child.vue
mounted() {
this.$emit("mounted");
}
2
3
4
5
6
7
8
以上需要手动通过 $emit 触发父组件的事件,更简单的方式可以在父组件引用子组件时通过 @hook 来监听即可,如下所示:
// Parent.vue
<Child @hook: mounted = "doSomething" > < /Child>
doSomething() {
console.log('父组件监听到 mounted 钩子函数 ...');
},
// Child.vue
mounted() {
console.log('子组件触发 mounted 钩子函数 ...');
},
// 以上输出顺序为:
// 子组件触发 mounted 钩子函数 ...
// 父组件监听到 mounted 钩子函数 ...
2
3
4
5
6
7
8
9
10
11
12
当然 @hook 方法不仅仅是可以监听 mounted,其它的生命周期事件,例如:created,updated 等都可以监听。
# 何时需要使用 beforeDestroy
- ① 解绑自定义事件 event.$off
- ② 消除定时器
- ③ 解绑自定义的 DOM 事件 如 window.scroll 等
# 父子组件生命周期钩子函数执行顺序?
beforeCreate 不能访问到 methods、data、computed、watch 上的方法和数据
created 可以调用 methods 中定义的方法,修改 data 的数据,并且可触发响应式变化、computed 值重新计算,watch 到变更等
Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:
加载渲染过程
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
子组件更新过程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
父组件更新过程
父 beforeUpdate -> 父 updated
销毁过程
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
# computed、watch 执行顺序
在 created 之前就会 就会进行初始化 computed 和 watch
看以下执行顺序图可以得出:
- 初始化时父元素 向 子元素传递数据分两个阶段,
(1) 一为父元素父 beforeMount 及之前的一个阶段,包括 data 中定义的赋值;
(2) 另一个阶段为,父元素 mounted 及其之后的阶段;在一个阶段中后面的赋值会替换前面的赋值;(如:父 created 覆盖父 data 中定义的),所以 watch 和 computed 会触发两次;
- watch 有 immediate 属性: 首次绑定的时候,是否执行 handler,默认 false
(1) 为 true 时,在子元素的 created 之前执行;
(2) 为 false 时 只有在父元素 mounted 之后值改变才会触发,否则是不会触发的;
- computed 执行值 computed 被引用处(数据变更时 watch 在 computed 之前执行),然后继续执行 computed 代码;computed 最早在 created 之后执行;