重学vue之vue生命周期|8月更文挑战

691 阅读3分钟

lifecycle.png 图片摘自 vue官方网站

ok,我会跟据这张图片+代码尽量把vue的生命周期说明白


new Vue()

创建一个vue实例,只有创建了vue实例,才会有vue生命周期。在vue项目中,每一个vue组件就可以算作是一个vue实例,也就是做每个组件都会有自己的生命周期。

init Events & Lifecycle

初始化事件与生命周期。but!此时数据代理还没有开始

beforeCreate

vue第一个生命周期,根据字面意思理解为创建之前。此时还无法访问实例对象中的任何数据

<template>
    <div>
        {{msg}}
    </div>
</template>

<script>
    export default {
        data(){
            return{
                msg:'Jsnewbie'
            }
        },
        beforeCreate(){
            console.log('beforeCreate',this)
            debugger
        }
    }
</script>

image.png

调试代码我们从控制台可以看到。“beforeCreate”确实输出了,但是this(vm,也就是vue的实例对象)中并没有我们写在data中的数据

init injections & reactivity

此时,仍然是初始化过程。初始化数据监测与数据代理。当这步完成后,才到了vue的第二个生命周期created

created

vue第二个生命周期,实例创建完成,此时可以通过this访问到vue实例中的数据

<script>
    export default {
        data(){
            return{
                msg:'Jsnewbie'
            }
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
            console.log(this)
            debugger
        }
    }

image.png

通过控制台可以看到数据代理与数据监测都已完成。我们是可以正常访问到vue实例中的数据的

beforeMount

vue第三个生命周期
在挂载之前。从图中可以看出,在createdbeforeMount中间,vue做了许多判断,比如判断页面中有没有根标签,有没有templete选项等。它做这些判断的原因只有一个,就是为了解析模版,并在内存中生成虚拟DOM
此时,在挂载前,并没有将虚拟DOM插入到页面中的真实DOM,页面中呈现的也是没有编译过的结构

<body>
    <div id="root">
        <h2>data中的msg{{msg}}</h2>
    </div>
</body>
<script>
    Vue.config.productionTip=false
    new Vue({
        el:"#root",
        data:{
            msg:"Jsnewbie"
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
        },
        beforeMount(){
            console.log("beforeMount")
            debugger
        }
    })
</script>

image.png

此时我们可以看到,在挂载前,页面中还是原始的DOM结构,并没有将虚拟DOM插入到页面真实DOM中(这里的代码跟前2个生命周期代码有所区别。上面的代码是cli创建的,并不能很好的说明问题,这里采用非脚手架演示)

created

vue第四个生命周期
挂载完成。此时,vue以将虚拟DMO插入到页面中的真实DOM

    new Vue({
        el:"#root",
        data:{
            msg:"Jsnewbie"
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
        },
        beforeMount(){
            console.log("beforeMount")
        },
        mounted(){
            console.log("mounted")
            
        }
    })

image.png

至此,vue初始化过程结束。我们可以在此生命周期内进行一些初始化操作,比如启动定时器。发送请求等等

beforeUpdate

vue第五个生命周期
在更新之前

 new Vue({
        el:"#root",
        data:{
            msg:"Jsnewbie"
        },
        methods:{
            changeMsg(){
                this.msg = "Jsnewbie666"
            }
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
        },
        beforeMount(){
            console.log("beforeMount")
        },
        mounted(){
            console.log("mounted")  
        },
        beforeUpdate(){
            console.log("beforeUpdate")
            console.log(this.msg)
            debugger
        }
    })

image.png

注意:通过控制台可以看到,在更新前,data中的msg与页面中的msg并不一致

Virtual DOM re-render and patch

在更新前与更新后中间这个过程中,vue会根据更新后的新数据生成新的虚拟DOM然后与旧的虚拟DOM进行比较。最终完成更新操作

updated

vue第五个生命周期
更新完成

new Vue({
        el:"#root",
        data:{
            msg:"Jsnewbie"
        },
        methods:{
            changeMsg(){
                this.msg = "Jsnewbie666"
            }
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
        },
        beforeMount(){
            console.log("beforeMount")
        },
        mounted(){
            console.log("mounted")  
        },
        beforeUpdate(){
            console.log("beforeUpdate")
        },
        updated(){
            console.log("updated")
            console.log(this.msg)
            debugger
        }
    })

image.png 此时更新后的数据与页面中的数据保持一致

beforeDestory & destory

这是vue中最后两个生命周期,也比较简单。

image.png 关于生命周期的销毁,上图是官方的解释
我们可以在beforeDestory中做一些收尾的工作(清除定时器等)

这里还事有一个比较有意思的事要说明一下。根据官方解释,如果我们调用了实例对象的$destory,则vue会解绑他的全部指令及事件监听器。直接上代码

 methods:{
            changeMsg(){
                console.log("数据被修改了!!!")
                this.msg = "Jsnewbie666"
            },
            remove(){
                console.log("销毁vue实例")
                this.$destroy()
            }
        },

image.png

注意看控制台,我是先点击的销毁实例,触发了destroyed这个生命周期函数,然后我在点击的修改数据这个按钮,可以看到这个changeMsg方法依然被触发!这里要说明一下,官方给的解释是vue会解绑他的全部指令及事件监听器,官网的这个事件监听器指的是vue的自定义事件,并不是原生的DOM事件。我们给button绑定的@click事件最终vue也会渲染成原生的DOM事件!!

OK,vue生命周期大概就这么多。最主要的还是初始化过程,用的最多的生命周期也mounted这个阶段(销毁和更新我是没怎么用过)