接触Vue两个月了,今天说一说vue里边很重要的生命周期,记得最开始接触的时候我问了一下周边的同事,html
这些生命周期都有什么用,获得的答案是mounted里边能够操做属性,你记住mounted就完事了,因而乎。。。vue
数据请求,mounted() 赋值 mounted(),执行方法,mounted(), 监听更新数据???搞不动了。。。ios
而后最近仔细的看了一遍Vue的生命周期,今天和你们分享一下我所了解的 axios
首先 什么是Vue的生命周期浏览器
Vue 实例从开始建立、初始化数据、编译模板、挂载Dom和渲染、更新和渲染、卸载等一系列过程,这是 Vue 的生命周期dom
vue的生命周期里边有八个生命周期钩子函数分别是函数
beforeCreat() 建立前性能
created()建立this
beforeMount()挂载前spa
mounted()挂载
beforeupdate()更改前
updated()更改
beforeDestroy()销毁前
destroyed()销毁
先来一张官方的生命周期图镇贴
这个生命周期如上图所示 实例初始化在这个生命周期遍历 data 对象下全部属性将其转化为 getter/setter
也就是说添加一个被观察者,因此咱们平时在项目中遇到在后来添加新的属性视图不更新就是这个缘由
在后来被添加的属性,没有被放到观察者对象中去 可是这个时候数据并无和模板创建连接 还不能操做属性
说到这里你可能会反驳我,打印的全都是undefined,你怕是在逗我
but 你能够经过$options(实例自定义属性,属于数据访问的一种和$date 平级) 看到data的值 注意data是个函数 他没执行 因此拿不到数据,用图来讲话
data(){ return{ a:"1" } }, beforeCreate(){ console.log("beforeCreate",this.$el,this.a) }, //beforeCreate undefined undefined
那么若是想在实例挂载完成后添加的属性触发视图更新的话能够用 $set 这个方法 这个方法会向被观察者对象里边新增你的属性
这时候咱们打印一下组件里的属性仍是不存在的
到这个生命周期的时候 实例已经被建立完毕 属性已经绑定 属性是能够操做的
可是dom还不存在 $el属性还不能够操做
这个生命周期能够进行axios请求 可是这个时候页面尚未被渲染出来 若是请求时间过长的话 会出现长时间的白屏
加loading可能会用户体验好一些
这个生命周期如上图所示 他会把template模板编译成html 还有执行render函数,返回一个虚拟dom 同第一句话 就是说
dom还拿不到
data(){ return{ a:"1" } }, beforeCreate(){ console.log("beforeCreate",this.$el,this.a) }, created(){ console.log("created",this.$el,this.a) this.a=2 console.log(this.a) }, //created undefined 1 //2
这个虚拟Dom接触的不是太多 简单来说就是经过js生成一个相似于dom树的那么一个东西
来看一下这个虚拟dom
大概就是这么一大串 ,刚看到的时候个人第一感受就是 真¥%…#…复杂 而后出于好奇 我打印了一下真实dom
更¥%……%复杂总而言之 一屏放不下 因此说大批量的操做dom 是很影响性能的一件事情 膜拜一下远方的各位大神
从图上来说 这个声明周期作的是模板编译,看网上的帖子有人能把$el打印出来 不太理解怎么打印出来的 本身试了一下
打印不出任何东西
beforeMount(){ console.log('beforeMount',this.$el,this.pickerMark) debugger }, //beforeMount undefined false
这个生命周期 el还未对数据进行渲染 仍是不能操做dom
这个生命周期 是我用的最多的 这个时候的虚拟dom已经被渲染到了真实的dom上边
这个生命周期里边咱们能够作的事情不少 好比数据请求或者赋值操做属性等等
mounted(){ console.log('mounted',this.$el,this.pickerMark) }, //mounted <div class="propaganda-form" arealistitem="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]" style="display: none;"></div> false
以上四个生命周期 每一个组件只执行一次,过去了就不会在执行了
咱们在mounted更新一个属性的话 beforeUpdate 和 updated 生命周期函数 会被触发 可是仅限于 被观察的属性作出的变化且被引用他们才会触发
并且须要注意的是 不要再updated 函数里边直接就修改属性 会进入死循环 好比说。。。。
浏览器崩溃了。。。。 若是你要用的话 必定要加判断条件 确保能跳出去的那种,我我的是很喜欢用updated这个生命周期函数的
由于以前我拿值什么的都是用的watch 可是vue并不推荐用 缘由说是很耗费资源 不算计算属性的话 这个updated 能够说是很方便了
可是若是变化的不是响应式的值 他就不会触发怎么办 以前研究过一个方法分享一下 就是说再date里边声明一个变量看成标记
而后把这个变量放到页面中 dispaly:none; 而后在你调用非相应的变量的时候 你在后边也调用一下这个标记 updated生命周期函数
是会执行的 这时候你能够加一些判断在update去执行一些东西 固然 后来认识了计算属性 就放弃了这个作法 计算属性是一种声明式的属性
他只会告诉你这个值是怎么构成的 很方便
这两个生命周期 用到的比较少 顾名思义 销毁前这个生命周期 的时候 仍是能够对元素进行操做的
以前在项目中用到的就是 高级搜索在销毁的时候判断是否有值 而后返回相应的状态
销毁这个生命周期执行事后 实例的属性和方法就不能再用了
上边讲了单个实例的生命周期,可是咱们在平时用到的 确定不会是一个组件, 那么父子组件 或者兄弟组件的生命周期又是什么样的
直接来一张图
上图能够看到 若是有父子组件的话 会先从父组件开始 到beforeMount 开始走子组件 到beforeMount 而后是子组件的一堆mounted 最后父组件
还能够看出 兄弟组件的话 是依次到beforeMount 而后按照顺序mounted
再来看一下update
有关联的话 他的顺序是 父beforeupdate 子beforeupdate 子updated 父updated
父组件没有关联的话 也不会触发子组件的生命周期
销毁也是这个顺序 就不一一上图了
你们 能够理解成递归 感受就是递归 ,那么若是递归的话 就存在一个做用域的问题 混入的时候 又是什么样的
你们都知道混入的时候组件里边属性和方法 会优先使用 可是生命周期是都会走的 相比你们猜也都猜到了
既然组件里边有方法的话会用组件的 那么混入必然是最外层的 刚才证明了一下想法 确实是这样
混入的生命周期的话 会在每一个声明周期的最前边 全部的生命周期 都会优先执行
以上是对vue生命周期的理解 可能有不足之处 但愿你们批评指正