文章目录
说说你对Vue生命周期的理解
为什么Vue中的data属性是一个函数而不是一 个对象?
说说你对Vue生命周期的理解
生命周期是什么
基本涵义可以通俗地理解为“从摇篮到坟墓”(Cradle-to-Grave)的整个过程在Vue中实例从创建到销毁的过程就是生命周期,即指从创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程
在Vue生命周期钩子会自动绑定 this 上下文到实例中,因此你可以访问数据,对 property 和方法进行运算这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())
生命周期整体流程
beforeCreate -> created
●初始化vue实例,进行数据观测
created
●完成数据观测,属性与方法的运算,watch、event事件回调的配置
●可调用methods中的方法,访问和修改data数据触发响应式渲染dom,可通过computed和watch完成数据计算
◆此时vm.$el 并没有被创建
created -> beforeMount
●判断是否存在el选项,若不存在则停止编译,直到调用vm.$mount(el)才会继续编译
●优先级:render > template > outerHTML
vm.el获取到的是挂载DOM的
beforeMount
●在此阶段可获取到vm.el
●此阶段vm.el虽已完成DOM初始化,但并未挂载在el选项上
beforeMount -> mounted
此阶段vm.el完成挂载,vm.$el生成的DOM替换了el选项所对应的DOM
mounted
●vm.el已完成DOM的挂载与渲染,此刻打印●vm.$el,发现之前的挂载点及内容已被替换成新的DOM
beforeUpdate
●更新的数据必须是被渲染在模板上的(el、template、render之一)
●此时view层还未更新
●若在beforeUpdate中再次修改数据,不会再次触发更新方法
updated
完成view层的更新
若在updated中再次修改数据,会再次触发更新方法(beforeUpdate、updated)
beforeDestroy
实例被销毁前调用,此时实例属性与方法仍可访问
destroyed
●完全销毁一个实例。可清理它与其它实例的连接,解绑它的全部指令及事件监听器
●并不能清除DOM,仅仅销毁实例
使用场景分析
●beforeCreate 执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务
●created 组件初始化完毕,各种数据可以使用,常用于异步数据获取
●beforeMount 未执行渲染、更新,dom未创建
●mounted 初始化结束,dom已创建,可用于获取访问数据和dom元素
●beforeUpdate 更新前,可用于获取更新前各种状态
●updated 更新后,所有状态已是最新
●beforeDestroy 销毁前,可用于一些定时器或订阅的取消
●destroyed 组件已销毁,作用同上
数据请求在created和mouted的区别
created是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成mounted是在页面dom节点渲染完毕之后就立刻执行的触发时机上created是比mounted要更早的两者相同点:都能拿到实例对象的属性和方法讨论这个问题本质就是触发的时机,放在mounted请求有可能导致页面闪动(页面dom结构已经生成),但如果在页面加载前完成则不会出现此情况建议:放在create生命周期当中
为什么Vue中的data属性是一个函数而不是一 个对象?
组件data定义函数与对象的区别
在我们定义好一个组件的时候,vue最终都会通过Vue.extend()构成组件实例
这里我们模仿组件构造函数,定义data属性,采用对象的形式
function Component(){
}
Component.prototype.data = {
count : 0
}
1
2
3
4
5
6
创建两个组件实例
const componentA = new Component()
const componentB = new Component()
1
2
修改componentA组件data属性的值,componentB中的值也发生了改变
console.log(componentB.data.count) // 0
componentA.data.count = 1
console.log(componentB.data.count) // 1
1
2
3
产生这样的原因这是两者共用了同一个内存地址,componentA修改的内容,同样对componentB产生了影响
如果我们采用函数的形式,则不会出现这种情况(函数返回的对象内存地址并不相同)
function Component(){
this.data = this.data()
}
Component.prototype.data = function (){
return {
count : 0
}
}
1
2
3
4
5
6
7
8
vue组件可能会有很多个实例,采用函数返回一个全新data形式,使每个实例对象的数据不会受到其他实例对象数据的污染
结论
●根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况
●组件实例对象data必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染。采用函数的形式,initData时会将其作为工厂函数都会返回全新data对象