Vue实战之生命周期初探

    xiaoxiao2022-07-14  177

    Vue 生命周期之旅

    每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会

    官方生命周期函数示意图

    生命周期示意图详解
    beforeCreate

    在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用 注意是数据观测和事件/监听配置之前调用,也就是说在此处访问this.$el,this.$data,实例中的属性或方法是访问不到的,即undefined 使用场景:可以定义一些静态属性或者加载动画

    created

    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见 data 和 methods 中的属性和方法均可访问,但vue实例的$em属性仍然是undefined 使用场景:进行ajax请求异步数据的获取、初始化数据,结束加载动画

    beforeMount

    在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。 由示意图可知在created和beforeMount两个钩子期间,首先判断是否有el属性,如果没有则生命周期终止,除非手动调用vm.$mount(el)方法, 如果有el属性,则再判断是否存在template,如果存在则编译template并执行render函数,如果没有则编译外部html作为模板进行编译 注意:此时的$el不再是undefined,紧紧是字符串模板,相关数据还未填充,template的编译优先级是高于outer html的 使用场景:

    mounted

    el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。 注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted,此时的$el为填充后的数据 使用场景:当需要操作dom的时候执行,可以配合$.nextTick 使用进行单一事件对数据的更新后更新dom

    beforeUpdate

    数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。 使用场景:在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

    updated

    由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。 注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated

    beforeDestroy

    实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。 注意:我们可以使用 vm.$destroy()进行手动销毁

    destroyed

    Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用 注意:对data的改变不会再触发周期函数,vue实例已解除事件监听和dom绑定,但dom结构依然存在

    生命周期以及使用场景
    生命周期解释使用场景beforeCreate在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用定义一些静态属性或者加载动画,el data computed watch methods上的方法和数据均不能访问created在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见初始化数据(计算或者转换等),结束加载动画beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用此时的$el是虚拟节点mountedel 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子可异步请求,操作DOMbeforeUpdate数据更新时调用,发生在虚拟 DOM 打补丁之前这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子可执行依赖的DOM操作beforeDestroy实例销毁之前调用。在这一步,实例仍然完全可用可用于销毁定时器,解绑全局事件,销毁插件对象destroyedVue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁DOM依然存在
    测试DEMO
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script> </head> <body> <div id="app"> <div :style="{color:color}"> <h6>{{ message + '这是在 outer html 中的' }}</h6> </div> </div> </body> <script> const vm = new Vue({ el:'#app', //template:"<h1>{{message +'这是在 vue 实例template中的'}}</h1>", data:{ message:'hello world', jumpUrl:'www.baidu.com', color:'orange' }, methods:{ tipTool(){ return 'hello vue lifecycle'; }, }, watch:{ color:(new_value , old_value) => { alert('字体颜色监听事件'); } }, beforeCreate:function(){ //在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 this.refererUrl = 'www.sina.com'; console.group('vue 生命周期 beforeCreate'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, created:function(){ // 在实例创建完成后被立即调用。在这一步, // 实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。 // 然而,挂载阶段还没开始,$el 属性目前不可见。 console.group('vue 生命周期 created'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, beforeMount(){ // 在挂载开始之前被调用:相关的 render 函数首次被调用。 console.group('vue 生命周期 beforeMount'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, mounted(){ // el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 // 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。 // 注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted console.group('vue 生命周期 mounted'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, beforeUpdate(){ // 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。 // 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行 console.group('vue 生命周期 beforeUpdate'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, updated(){ // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 // 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。 // 注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated console.group('vue 生命周期 updated'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, beforeDestroy(){ //实例销毁之前调用。在这一步,实例仍然完全可用 console.group('vue 生命周期 beforeDestroy'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); }, destroyed(){ //Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 console.group('vue 生命周期 destroyed'); console.log('vue实例的el',this.$el); console.log('vue实例的data',this.$data); console.log('vue实例的data中的数据 message ',this.message); console.log('vue实例的data中的数据 refererUrl ',this.refererUrl); const res = this.tipTool(); console.log('vue实例的方法 ',res); } }); </script> </html>

    参考文章:1 2

    最新回复(0)