vue哪个生命周期可以操作html,Vue中生命周期的理解

vue生命周期

生命周期可以分为四个阶段,初始化阶段,模板编译阶段,挂载阶段,已挂载和卸载阶段。

el :选择器

$el:对应选择器的template模板(html代码)

render:也是vue实例中的一项,其参数更接近vue解析器,按优先级,render参数 > vue实例对象中有template > 外部的HTML模板 后面两个也是将其编译成render函数;【注意】render选项参数比template更接近Vue解析器!所以优先级如下:

render函数选项  > template参数  > 外部HTML

$mount :当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中,假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载。例如:

new Vue({内部无el项}).$mount('#app')是延迟加载,同下面的语句相同

new Vue({el:"#app",***})

computed计算属性可用于快速计算视图(View)中显示的属性。这些计算将被缓存,并且只在需要时更新.

watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象,一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据.

methods每当触发重新渲染时,方法的调用方式将总是再次执行函数。因此,函数必须是一个纯函数。它不能有副作用。输出只能依赖于传递给函数的值。

HTML

{{ message }}

{{message + '这是在outer HTML中的'}}

js

var app = new Vue({

el: '#app',

data: {

message : "xuxiao is boy"

},

template:"

{{message +'这是在template中的'}}

",

// render: function(createElement) {

// return createElement('h1', 'this is createElement')

// }

})

最终结果

vue哪个生命周期可以操作html,Vue中生命周期的理解_第1张图片

vue哪个生命周期可以操作html,Vue中生命周期的理解_第2张图片

vue哪个生命周期可以操作html,Vue中生命周期的理解_第3张图片

vue整个过程做了些什么

new Vue()创建实例

vue项目都是通过组件化进行实现的,一个页面通过若干组件组成,构成一个组件树,

每一个组件都通过一个vue实例来进行管理,

每当要渲染一个组件前,都会为该组件创建一个vue实例来管理组件中的数据和事件方法。

通过new Vue()创建实例时,实际创建了一个vue实例的空壳,初始化生命周期和事件

注意:这时候实例中的data选项还没有数据,所以在beforecreated中无法访问到data中的数据

初始化阶段

beforecreate

在这个阶段,完成实例初始化,

初始化非响应式变量 this指向创建的实例;

可以在这加个loading事件;

data computed watch methods上的方法和数据均不能访问,这个时候的Vue实例还什么都没有,

$route对象是存在的,可以根据路由信息进行重定向之类的操作;

这个阶段的data对象未完成初始化,el也没有完成初始化;

DOM还没有开始

注意:在beforecreated中千万不要去修改data中赋值的数据,最早也要在create里面去做(添加一些行为)

created 【创建完成】

在模板渲染成HTML前调用,即通常初始化一些属性值,然后再渲染成视图, 未挂载DOM;created时还没完成挂载,无法通过id等获得DOM元素;

实例创建完成 完成数据(data props computed)的初始化 导入依赖项。

可访问data computed watch methods上的方法和数据 ;

不能访问el【初始化还未完成】,ref为空数组 ;不能对元素进行操作;

可在这结束loading,

还做一些初始化,实现函数自执行,

可以对data数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。

el还是undefined,

而数据已经与data中的属性进行绑定(放在data中属性当值发生改变的同时,视图也会发生变化),

在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

若在此阶段进行的 DOM 操作一定要放在 Vue.nextTick() 的回调函数中;因为created() 钩子函数执行的时候 DOM 其实并未进行任何渲染

Vue.nextTick( [callback, context] ):在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

模板编译阶段

beforemount & mount

在created后,beforemount前,会检查el选项,没有就会调用vm.$mount(),然后就会继续检查template,没有的话就绑定el选项的html,进入beforemount后,编译模板为虚拟的DOM,,开始render,将虚拟DOM渲染到页面上;

从created到beforeMount的过程中,

var app = new Vue({

el: '#app',

data: {

message : "xuxiao is boy"

},

template:"

{{message +'这是在template中的'}}

",

// render: function(createElement) {

// return createElement('h1', 'this is createElement')

// },

首先会判断vue实例中有没有el选项,如果有的话则进行下面的编译,但是如果没有el选项,则停止生命周期,直到vue实例上调用vm.$mount(el)。

如果有el,再判断是否有template参数,如果有,则把其当作模板编译成render函数,

bVbzHoJ?w=1015&h=117

如果没有,则把外部的html作为模板编译。template中的模板优先级高于outer HTML模板。

vue哪个生命周期可以操作html,Vue中生命周期的理解_第4张图片

这是把outerHTML当作模板编译了

{{ message }}

{{message + '这是在outer HTML中的'}}

如果把实例中render function选项的注释去掉,则直接用render function里的,得到网页如下

vue哪个生命周期可以操作html,Vue中生命周期的理解_第5张图片

所以按优先级来说 render function>template>outerHTML

————————————————

在vue对象中还有一个render函数,它是以createElement作为参数,然后做渲染操作,而且我们可以直接嵌入JSX.

综合排名优先级:render函数选项 > template选项 > outer HTML.

挂载阶段

beforeMount【挂载之前】

在这个阶段,$el还只是我们在HTML里面写的节点。$el属性已存在,是虚拟dom,只是数据未挂载到模板中;有了el,编译了template|/outerHTML 能找到对应的template,并编译成render函数

载入前(完成了data和el数据初始化),

但是页面中的内容还是vue中的占位符,

$el属性已存在,是虚拟dom,只是数据未挂载到模板中。

data中的message信息没有被挂在到Bom节点中,

在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

mounted 【成功挂载】

完成创建vm,

完成el的双向绑定,完成挂载dom和渲染,可以在这个阶段对挂载的DOM进行操作;

ref 可在这发起后端请求,拿回数据,配合路由钩子做一些事情; 可对DOM 进行操作

载入后html已经渲染(ajax请求可以放在这个函数中),把vue实例中的data里的message挂载到BOM节点中去

beforeUpdate

更新前状态(view层的数据变化前,不是data中的数据改变前),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染

只有view上面的数据变化才会触发beforeUpdate和updated,仅属于data中的数据改变是并不能触发;

数据更新之前 可在更新前访问现有的DOM,如手动移除添加的事件监听器;

beforeUpdate是指view层的数据变化前【具体的可以用this.$el.innerHTML可以看出没有改变】,不是data中的数据改变前触发。因为Vue是数据驱动的

updated

数据已经更改完成,dom也重新render完成【具体的可以用this.$el.innerHTML可以看出已经改变了】

完成虚拟DOM的重新渲染和打补丁; 组件DOM 已完成更新; 可执行依赖的dom 操作 注意:不要在此函数中操作数据,会陷入死循环的。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher取而代之。

view层的数据更新后,data中的数据同beforeUpdate,都是更新完以后的。

注意:会发现beforeUpdate和updated钩子函数中的$el一样,根据官方理解beforeUpdate应该指向虚拟dom,所以才会一样,而dom中的真正内容不一样,但是beforeMount和mouted钩子函数中为什么又会有区别呢?感觉是设计的不足之处。**_

activated

在使用vue-router时有时需要使用来缓存组件状态,这个时候created钩子就不会被重复调用了,

如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发

deactivated

keep-alive 组件被移除时使用

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

说明:

beforeDestroy(){

console.group('beforeDestroy 销毁前状态==========>>');

console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement]

console.log(this.$el);

console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]

console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!

},

destroyed

官方解释:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

说明:执行destroy方法后,对data的改变不会再触发周期函数,此时的vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。

destroyed(){

console.group('destroyed 销毁完成状态==========>>');

console.log("%c%s", "color:red", "el : "+this.$el); //[object HTMLDivElement]

console.log(this.$el);

console.log("%c%s", "color:red", "data : "+this.$data); //[object Object]

console.log("%c%s", "color:red", "message: "+this.message); //今天周二了!!!

},

具体使用

beforeCreate:这个时候data,watcher,methods统统没有,这个时候的Vue实例还什么都没有,但是$route对象是存在的,可以根据路由信息进行重定向之类的操作。

vue哪个生命周期可以操作html,Vue中生命周期的理解_第6张图片

vue哪个生命周期可以操作html,Vue中生命周期的理解_第7张图片

mouted和created

vue哪个生命周期可以操作html,Vue中生命周期的理解_第8张图片

父子组件嵌套时触发钩子函数顺序

加载渲染过程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新过程

父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程

父beforeUpdate->父updated

销毁过程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

总结

beforecreate:可以在这加个loading事件

created :在这结束loading,还做一些初始化,实现函数自执行

mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情

beforeDestory: 你确认删除vue实例了吗?

destoryed :当前实例已被销毁,解绑相关指令和事件监听器

你可能感兴趣的:(vue哪个生命周期可以操作html,Vue中生命周期的理解)