AWebManCN

Menu

【干货】详解vue生命周期

生命周期定义

每个vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。详细来说,就是Vue实例从开始创建,初始化数据,编译模板,挂在dom->渲染,更新->渲染,卸载等一系列过程,我们称这是vue的生命周期,各个阶段有相对应的事件钩子。

钩子函数:当代码执行到特定阶段的时候会调用的函数,也是回调函数。

生命周期示意图

代码解析生命周期

1.new Vue() 创建实例

2.初始化事件和生命周期

3.beforeCreate

代码:

 let vm = new Vue({
    // 当前这个实例他的父亲是谁 儿子谁 有一套
    beforeCreate(){
        console.log(this); 
        console.log('---beforeCreate---');    
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
复制代码
n

从打印出来的this,可以看到此时发布订阅 emit等vue原生API已经初始化完成。但是不能访问到data,computed,watch,methods上的方法和数据。这个钩子函数不能做业务逻辑,一般情况下这个钩子函数可以做的事情:在每个组建中增加一些特定的属性,例如混合。

4.初始化注入和校验

5.created

el,

这个实例已经实现了数据劫持,把方法、计算属性 也都挂载到了实例,不能获取到真实的dom元素。不能访问到 ref属性内容未空数组。 这个钩子函数可以发送axios请求把请求回来的数据保存到data中。

let vm = new Vue({
    beforeCreate(){
        console.log(this);
        console.log('---beforeCreate---'); 
    },
    created(){
        console.log(this);
        console.log('---created---');
        debugger;
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
复制代码

6.beforemount

接下来就是渲染,但是在渲染之前会先判断“是否有制定的el选项”,正常的写法:el:'app',另一种用:vm.$mount('app')

$mount 可以指定一个元素,不指定元素的话,内部会默认渲染到一个内存中的节点
let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')    
    },
    created(){
        console.log(this) 
        console.log('---created---') 
    },
    beforeMount(){
        console.log('---beforeMount---') 
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount()
复制代码

虽然渲染失败了,但是走到了beforeMount这个钩子函数,它的要求是要么有个template,或者有个render函数。 把两者中一个加上:

render(){
        
    },
template:'<div>hello</div>',
复制代码

验证一下我们之前没有指定el,渲染在内存中,我们把它挂载到页面中去。

vm.$mount()
console.log(vm.$el)
document.body.appendChild(vm.$el)
复制代码

好处:可以把渲染好的元素插入到自己想要的节点中。

在生命周期流程图中,判读完el选项后,就会再判读是否有“指定的template选项”,是就将template编译到render函数中,没有则将el外部的HTML作为template 编译。 什么叫做el外部的HTML?就是我们常用:

<div id="app"></div>
vm.$mount('#app')
复制代码

这个div就是el外部的HTML,再统一编译到render函数中。

let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')    
    },
    created(){
        console.log(this) 
        console.log('---created---') 
    },
    render(){
        console.log('---render---') 
    },
    template:'<div>hello</div>',
    beforeMount(){
        console.log('---beforeMount---') 
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount('#app')
console.log(vm.$el)
document.body.appendChild(vm.$el)
复制代码

如果有了render就不会使用template,它内部会把template渲染成render方法,所以在挂载之前会调用render方法。

优先级关系:render>template>out html

beforeMount 做的事情就是调用render方法,但是一般不会增加业务逻辑

7.mounted

实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。

 let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')    
    },
    created(){
        console.log(this) 
        console.log('---created---') 
    },
    template:'<div>hello</div>',
    beforeMount(){
        console.log('---beforeMount---') 
    },
    mounted(){
        console.log('---mounted---') 
        console.log(vm.$el)
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount('#app')
复制代码

8.beforeupdate

vue 更新方式是组件级别的,比如我们项目会有许多组件,在根组件中引用3个组件,其中一个组件更新重新渲染了(异步渲染),另外两个不会重新渲染。

可以在这个钩子函数中,增加一些数据更新,不会导致试图多次更新。 响应式数据更新时调用,发生在虚拟DOM打补丁之前。 组件更新之前执行的函数。 数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前。

<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')    
    },
    created(){
        console.log(this) 
        console.log('---created---') 
    },
    beforeMount(){
        console.log('---beforeMount---') 
    },
    mounted(){
        console.log('---mounted---') 
        console.log(vm.$el)
    },
    beforeupdate(){
        console.log('---beforeupdate---') 
    },
    data(){
        return{
            msg:'10'
        }
    }
})
vm.$mount('#app')
</script>
复制代码

数据是应用到视图上才会变化。

9.updated

虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作.

这个钩子函数就不要再去更新数据,可能会发生死循环
updated(){
        this.msg= Math.random();
        console.log('---updated---') 
    },
复制代码

更新后会重新渲染,同时再走一边rander方法

10.beforeDestroy

实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例 这个钩子函数一般做事件的移除、清空定时器

11.destory

常见的销毁方式:手动( vm.$destory()移除所有的观察者 )、移除组件、路由切换 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。视图并不会刷新,
作者:奚奚的鸭
链接:https://juejin.im/post/5e81e9e16fb9a03c3c350918
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

— 于 共写了3415个字
— 文内使用到的标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注