vue生命周期

9次阅读

共计 443 个字符,预计需要花费 2 分钟才能阅读完成。

创建阶段

  • new Vue({}) 创建一个空的实例对象,这个对象上只有生命周期函数和一些默认事件。
  • 生命周期函数 beforeCreate 执行
  • 初始化 datamethods
  • 生命周期函数 created 执行
  • 编译模板:通过编译将 template 模板转换成渲染函数 (render ),执行渲染函数就可以得到一个虚拟节点树(内存中)
  • 生命周期函数 beforeMount 执行
  • 将内存中编译好的模板真实的替换到页面中去
  • 生命周期函数 mounted 执行,实例完全创建好了即实例初始化完毕,创建阶段完毕

运行阶段

  • data 被改变时触发生命周期函数 beforeUpdate 执行,data 是最新的,页面还未更新(旧的页面)
  • 根据最新的 data 重新渲染虚拟 DOM,并挂载到页面上,完成 ModelView 的更新
  • 生命周期函数 updated 执行,此时 data 和页面都是最新的

销毁阶段

  • 生命周期函数 beforeDestroy 执行,vue 实例进入销毁阶段
  • 销毁数据、方法、子组件、事件监听器 …
  • 生命周期函数 destroyed 执行, 组件完全被销毁
正文完
 0

vue生命周期

9次阅读

共计 3190 个字符,预计需要花费 8 分钟才能阅读完成。

接触 Vue 两个月了,今天说一说 vue 里边很重要的生命周期,记得最开始接触的时候我问了一下周边的同事,

这些生命周期都有什么用,得到的答案是 mounted 里边可以操作属性,你记住 mounted 就完事了,于是乎。。。

数据请求,mounted()赋值 mounted(),执行方法,mounted(),监听更新数据???搞不动了。。。

然后最近仔细的看了一遍 Vue 的生命周期,今天和大家分享一下我所了解的

首先 什么是 Vue 的生命周期

Vue 实例从开始创建、初始化数据、编译模板、挂载 Dom 和渲染、更新和渲染、卸载等一系列过程,这是 Vue 的生命周期

vue 的生命周期里边有八个生命周期钩子函数分别是

  • beforeCreat() 创建前
  • created()创建
  • beforeMount() 挂载前
  • mounted()挂载
  • beforeupdate()更改前
  • updated()更改
  • beforeDestroy() 销毁前
  • destroyed()销毁

先来一张官方的生命周期图镇贴

beforeCreate 实例创建前

这个生命周期如上图所示 实例初始化在这个生命周期遍历 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 这个方法 这个方法会向被观察者对象里边新增你的属性

这时候我们打印一下组件里的属性还是不存在的

created 实例创建

到这个生命周期的时候 实例已经被创建完毕 属性已经绑定 属性是可以操作的

但是 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 是很影响性能的一件事情 膜拜一下远方的各位大神

beforeMount 挂载前

从图上来讲 这个声明周期做的是模板编译,看网上的帖子有人能把 $el 打印出来 不太理解怎么打印出来的 自己试了一下

打印不出任何东西

        beforeMount(){console.log('beforeMount',this.$el,this.pickerMark)
            debugger
        },
    //beforeMount undefined false

这个生命周期 el 还未对数据进行渲染 还是不能操作 dom

mounted 挂载

这个生命周期 是我用的最多的 这个时候的虚拟 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

以上四个生命周期 每个组件只执行一次,过去了就不会在执行了

beforeUpdate 更新前 Updated 更新

我们在 mounted 更新一个属性的话 beforeUpdate 和 updated 生命周期函数 会被触发 但是仅限于 被观察的属性做出的变化且被引用他们才会触发

而且需要注意的是 不要再 updated 函数里边直接就修改属性 会进入死循环 比如说。。。。

浏览器崩溃了。。。。如果你要用的话 一定要加判断条件 确保能跳出去的那种,我个人是很喜欢用 updated 这个生命周期函数的

因为之前我拿值什么的都是用的 watch 但是 vue 并不推荐用 原因说是很耗费资源 不算计算属性的话 这个 updated 可以说是很方便了

但是如果变化的不是响应式的值 他就不会触发怎么办 之前研究过一个方法分享一下 就是说再 date 里边声明一个变量当作标记

然后把这个变量放到页面中 dispaly:none;然后在你调用非相应的变量的时候 你在后边也调用一下这个标记 updated 生命周期函数

是会执行的 这时候你可以加一些判断在 update 去执行一些东西 当然 后来认识了计算属性 就放弃了这个做法 计算属性是一种声明式的属性

他只会告诉你这个值是怎么构成的 很方便

beforeDestroy 销毁前 destroy 销毁

这两个生命周期 用到的比较少 顾名思义 销毁前这个生命周期 的时候 还是可以对元素进行操作的

之前在项目中用到的就是 高级搜索在销毁的时候判断是否有值 然后返回相应的状态

销毁这个生命周期执行过后 实例的属性和方法就不能再用了

生命周期的顺序

上边讲了单个实例的生命周期,但是我们在平时用到的 肯定不会是一个组件,那么父子组件 或者兄弟组件的生命周期又是什么样的

直接来一张图

上图可以看到 如果有父子组件的话 会先从父组件开始 到 beforeMount 开始走子组件 到 beforeMount 然后是子组件的一堆 mounted 最后父组件

还可以看出 兄弟组件的话 是依次到 beforeMount 然后按照顺序 mounted

再来看一下 update

有关联的话 他的顺序是 父 beforeupdate 子 beforeupdate 子 updated 父 updated

父组件没有关联的话 也不会触发子组件的生命周期

销毁也是这个顺序 就不一一上图了

大家 可以理解成递归 感觉就是递归,那么如果递归的话 就存在一个作用域的问题 混入的时候 又是什么样的

大家都知道混入的时候组件里边属性和方法 会优先使用 但是生命周期是都会走的 相比大家猜也都猜到了

既然组件里边有方法的话会用组件的 那么混入必然是最外层的 刚才证实了一下想法 确实是这样

混入的生命周期的话 会在每个声明周期的最前边 所有的生命周期 都会优先执行

以上是对 vue 生命周期的理解 可能有不足之处 希望大家批评指正

正文完
 0

Vue 生命周期

9次阅读

共计 1431 个字符,预计需要花费 4 分钟才能阅读完成。

生命周期函数
生命周期函数就是 Vue 实例在某一个时间点会自动执行的函数
简单来说就是,钩子(生命周期函数)就好像是把人的出生到死亡分成一个个阶段,你肯定是在出生阶段起名字,而不会在成年或者死亡的阶段去起名字。或者说你想在出生阶段去约炮,也是不行的。组件也是一样,Vue 在实例化一个组件时会在特定的阶段调用特定的方法,调用的这个方法就叫钩子方法,比如 Vue 在实例化组件之初按顺序调用 beforeCreated,created,beforeMounted,mounted,每个阶段组件内部的属性都是不一样的,比如 created 钩子时视图还没有渲染,就不能做一些 dom 操作。所以一般特定的钩子做特定的事,比如 ajax 获取数据就可以在 mounted 阶段,当然放在 created,beforeMounted 也是可以的,因为 ajax 是异步的嘛,ajax 之后的回调会放在事件队列的尾部,此时实例化组件整个过程会在 ajax 回调之前执行完毕。所以 ajax 操作放在 created,mounted 里面都是可以的。

在调用 new vue 时,Vue 会帮我们去创建一个 Vue 的实例,创建过程其实并不是像我们想的这么简单,首先它会初始化一些事件和生命周期相关的内容,
在初始化完成的时候,Vue 会自动的执行一个 beforeCreate 函数,
之后会初始化一些外部的注入和一些双向绑定相关的事情,当这一部分完成后,基本上 Vue 的初始化就都完成了。在这个节点上又有一个 created 函数被自动执行
let vm = new Vue({
el:’#app’,
beforeCreate(){
console.log(‘beforeCreate’)
},
created(){
console.log(‘created’)
}
})
这个时候 Vue 的初始化已经基本结束了,然后它会询问一个条件:你这个 Vue 实例里是否有 el 这个选项
如果有就会询问是否有 template 这个选项:

如果没有就会走右侧的这个分支,
如果这个实例没有 templeate,就会将 el 这个根节点当做模版,来进行渲染

有就会走左侧的分支
把 template 作为模版去渲染

上面这一步走完后,并没有立即渲染,在渲染之前会执行 beforeMount 函数
当这个函数执行之后,模版结合数据最终生成的 Dom 元素,会被挂载到页面之上
当被挂载到页面之上,也就是 hello world 显示到页面之上,这时候 mounted 函数会被执行(页面挂载之后会执行)
let vm = new Vue({
el:’#app’,
beforeCreate(){
console.log(‘beforeCreate’)
},
created(){
console.log(‘created’)
},
beforeMount(){
console.log($el) //<div id=”app”></div>
console.log(‘beforeMount’)
},
mounted(){
console.log($el) //<div id=”app”>Hello world</div>
console.log(‘mounted’)
}
})
这里也验证了 beforeMount 执行时,页面还没有被渲染,mounted 执行时,页面已经被渲染了
在往下是 beforeDestory(实例被销毁前执行),destoryed(实例销毁完成后执行)
当数据被改变时,会执行 beforeUpdate(数据被改变,还没渲染之前触发),updated(数据被改变,渲染完成后触发)

正文完
 0