什么是vue生命周期

Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称为Vue的⽣命周期。

什么是生命周期钩子

在vue实例的生命周期中会提供一些特定阶段可供调用的函数,这些函数会被调用,程序员可在实例的对应生命周期阶段中进行操作

生命周期钩子

  • beforeCreate()

    这个阶段属于页面初始化之前(vue实例化之前)
    不能拿到数据,方法,Dom元素
    不能获取到绑定实例的el

  • created()

    页面初始化之后(Vue实例化之后)
    可以获取数据,方法
    不能获取到el,Dom元素
    虚拟dom并未生成
    此阶段并未开始解析模板,页面并不能显示完整信息

  • beforeMount()

    挂载前
    虚拟dom渲染完成, 真实Dom并未生成
    所有对Dom节点的操作都无效

  • mounted()

    挂载后
    mounted 阶段 真实dom生成完成 并渲染到页面上
    可以 获取dom元素

  • beforeUpdate()

    数据更新之前触发
    检测到数据的更新, 但是还未更新Dom

  • updated()

    数据更新完成之后触发
    检测到数据的更新并更新Dom

  • beforeDestroy()

    组件即将销毁时触发

  • destroyed()

    组件销毁后触发
    实例被销毁后vm实例还会存在

  • activated()

    缓存路由的生命周期钩子
    keep-alive组件激活时使用(在进入缓存路由时调用)
    在mounted钩子后执行

  • deactivated()

    缓存路由的生命周期钩子
    keep-alive组件停用时调用(在离开缓存路由时调用)

    /* 
       使用缓存路由后就不存在beforeDestroy、destroyed
       钩子,因为这个组件路由被缓存下来了,所以不会触发
    */
    
  • errorCaptured()

    当子孙组件出现错误时触发


图解

在这里插入图片描述


代码

<body>

    <div id="app">
        <p>{{list}}</p>
        <button ref="btn" @click="Func()">点击</button>
    </div>

    <!-- 
        <component :is='componentsName'>
                    内置组件,根据is属性来显示对应的组件;
                    is属性的属性值保持和组件名字一致;
                    使用v-bind绑定组件,可以动态切换组件
                    然后可以显示对应的组件
                    每次能动态显示一个组件,
                    当切换下一个组件时,当前组件要销毁(与缓存相对)


        Vue.$nextTick(callback)
                    在下次 DOM 渲染结束之后执行延迟回调。

                    在修改数据之后立即使用这个方法,获取更新后的 DOM。
        
    
                    Vue.nextTick(function () {
                    // DOM 更新了
                    })
        
                    // 没有提供回调,则返回一个 Promise
                    Vue.nextTick()
                        .then(function () {
                            // DOM 更新了
                        })

    -->

    <script>
        new Vue({
            el: '#app',

            data() {
                return {
                    list: ['app', 'cesi']
                }
            },

            methods: {
                Func() {
                    // alert('@');
                    this.list.push('123');
                }
            },

            // vue实例化之前------无法访问到vm中的属性和方法
            // 无法获取到 el, data,dom, 方法
            beforeCreate() {
                console.log('=====beforeCreate=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
                this.$nextTick(() => {
                    console.log('数据的初次渲染完成后的调用');
                })
                debugger;
            },

            /*
                vue实例化完毕---完成数据代理

                可以获取到
                    data数据 , 方法, 
                但是无法获取到
                    el, dom元素

                虚拟dom并未生成
                此阶段并未开始解析模板,页面并不能显示完整信息
            */
            created() {
                console.log('=====created=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
                debugger;
            },


            // 挂载前
            // 虚拟dom渲染完成, 真实Dom并未生成
            // 所有对Dom节点的操作都无效
            // 获取不了button
            beforeMount() {
                console.log('=====beforeMount=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
                console.log(this.$refs);
                debugger;
            },

            // 挂载后
            // mounted 阶段 真实dom生成完成 并渲染到页面上
            //  可以 获取dom元素
            mounted() {
                console.log('=====mounted=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
                console.log(this.$refs);
                debugger;
            },


            // 数据更新之前触发
            // 检测到数据的更新, 但是还未更新Dom
            beforeUpdate() {
                console.log('=====beforeUpdata=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);

                this.$nextTick(() => {
                    console.log('数据更新渲染完成之后的输出');
                });

                debugger;
            },

            // 数据更新完成之后触发
            // 检测到数据的更新并更新Dom
            updated() {
                console.log('=====updataed=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
                debugger;
            },

            // 缓存路由的生命周期钩子
            // keep-alive组件激活时使用(在进入缓存路由时调用)
            // 在mounted钩子后执行
            activated() {
                console.log('=====activated=====');
            },

            // 缓存路由的生命周期钩子
            // keep-alive组件停用时调用(在离开缓存路由时调用)

            /* 
                使用缓存路由后就不存在beforeDestroy、destroyed
                钩子,因为这个组件路由被缓存下来了,所以不会触发
            */
            deactivated() {
                console.log('=====deactivated=====');
            },

            // 组件即将销毁时触发
            beforeDestroy() {
                console.log('=====beforeDestroy=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
            },

            // 组件销毁后触发
            // 实例被销毁后vm实例还会存在
            destroyed() {
                console.log('=====destroyed=====');
                console.log('el:' + this.$el);
                console.log('list:' + this.list);
                console.log('fnc:' + this.Func);
            },

            // 当子孙组件出现错误时触发
            errorCaptured(err, vm, info) {

            },



            /* 
                引入路由组件钩子
            */

            // 组件守卫----进入组件时触发---先于生命周期钩子(beforeCreate)触发
            beforeRouteEnter(to, from, next) {
                // ...
            },

            // 组件守卫---离开组件时触发---先于实例销毁钩子(beforeDestroy)触发
            beforeRouteLeave(to, from, next) {
                // ...
            }
        })


        // 执行顺序

        // 进入、离开(无缓存keep-alive, 包含组件守卫)
        // beforeRouteEnter => beforeCreate => created =>
        // beforeMount => mounted => beforeUpdate => updated =>
        // beforeRouteLeave => beforeDestroy => destroyed

        // 进入、离开(有缓存keep-alive, 包含组件守卫)
        // beforeRouteEnter => beforeCreate => created =>
        // beforeMount => mounted => activated => beforeUpdate =>
        // updated => beforeRouteLeave => deactivated

    </script>
</body>

vue2生命周期与vue3生命周期的区别

  • 改变了两个生命周期钩子
    只是改变了命名,使其更加贴切组件卸载的含义
组件销毁前 => 组件卸载前

beforeDestroy => beforeUnmount

组件销毁后 => 组件卸载后

destroyed => unmounted
  • 生命周期流程变化
    在这里插入图片描述
    流程上相较与Vue2区别在于实例化vue时,
    2中是实例之后 初始化之后再检测绑定el
    3中则是在实例化Vue时绑定el,如果不绑定则后续钩子无法执行
Logo

前往低代码交流专区

更多推荐