Vue 的生命周期 详细解析(使用场景等)

Vue生命周期图:

 

 

一、生命周期图的解读

new Vue():首先需要创建一个 Vue的实例对象

Init Events & Lifecycle :初始化:生命周期、事件(如:v-once),但数据代理还未开始(vm._data还未创建)

1、第一对:beforeCreate() 和 create()

(1)beforeCreate() : 无法通过vm访问到data中的数据、methods中的方法

Init injections & reactivity:初始化:数据监测、数据代理(监测数据变化,给对象中的属性配置getter\setter,对方法进行二次包装)

(2) created() : 可以通过vm访问到data中的数据、methods中配置的方法

Vue开始解析模板,生成虚拟DOM(内存中),页面还不能显示解析好的内容:Has "el" option? :是否有el配置项,如果有,跳到“Has template option?”,如果没有,当调用了vm.$mount(#root) 时,接着跳到“Has template option?”;是否有template选项,如果没有,以el的外标签html作为 模板(<div id="root"></div>);如果有,Compile template into render function ,将模板编译成渲染函数,替换掉html中的 <div id="root"></div>

2、第二对:beforeMount() 和 mount()

(1)beforeMount():页面呈现的是未经Vue 编译的DOM 结构;所有对DOM的操作,最终都不奏效

Create vm.$el and replace “el” with it :将内存中的 虚拟DOM转为真实DOM插入页面,vm.$el存放虚拟DOM ,el存放真实DOM(vm.$el instanceof HTMLElement 得出 true)

(2)mount():页面中呈现的是经过Vue编译的DOM;对DOM的操作均有效(尽可能避免操作DOM);至此初始化过程结束,一般在此进行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作

3、第三对:beforeUpdate() 和 update()

when data changes ,当data中的数据发生改变

(1)beforeUpdate():数据是新的,但页面是旧的,即:页面尚未和数据保持同步

Virtual DOM re-render and patch, 虚拟DOM和真实DOM做比较,并重新渲染DOM

(2)updated():数据是新的页面也是新的,即:页面和数据保持同步

 4、第4对:beforeDestroy() 和 destroy()
when vm.$destroy() is called,当vm中的销毁方法被调用时,调用如下2个生命周期方法
vm.$destroy() : 清理它与其他实例的连接,解绑它的全部指令事件监听器
(1)beforeDestroy():vm中所有的:data、methods、指令等都处于可用状态,马上要执行销毁过程,一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作
Teardown watchers,child components and event listeners, 移除所有监视 子组件 和事件监听器 
(2)destroyed():收尾工作在 beforeDestroy方法中做了,destroy方法一般不做处理
 
其他:
1、buforeCreate():数据监听和数据代理创建之前(_data 、getter和setter)
2、比较重要的2个生命周期函数: mounted 和 beforedestroy
(1)mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等(初始化操作)
(2)beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等(收尾工作)
 
关于销毁Vue实例
(1)销毁后,借助Vue开发者工具 看不到任何信息
(2)销毁后自定义事件会失效,但原生DOM事件依然有效
(3)一般不会再beforDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
 
教学视频:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=52&spm_id_from=pageDriver&vd_source=60a28e8364654bee938864b1d19905ec
 第 49、50、51、52 集
 
练习:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 生命周期</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h3 :style="{opacity}">欢迎学习Vue</h3>
        <h4 v-text="n"></h4>
        <h4>n:{{n}}</h4>
        <button @click="add">n++</button>
        <button @click="bye">销毁vm</button>
    </div>
</body>
<script type="text/javascript">
    Vue.config.productionTip = false;
   const vm = new Vue({
        el:"#root",
        // template:`
        // <div>
        //     <h3 :style="{opacity}">欢迎学习Vue</h3>
        //     <h4>n:{{n}}</h4>
        //     <button @click="n++">n++</button>
        // </div>
        // `,
        data:{
            opacity:1,
            n:1
        },
        methods:{
            add(){
                console.log("add")
                this.n++
            },
            bye(){
                console.log("bye")
                vm.$destroy();
            }
        },watch:{
            n(){
                console.log("n变了")
            }
        },
        beforeCreate(){
            console.log("beforeCreate:");
            console.log("this",this);
            debugger;
            //n 还没有进行数据代理
        },
        created(){
            console.log("create");
            //console.log("this:",this);
            //debugger;
        },
        beforeMount(){
            console.log("beforeMount");
            // console.log("this:",this);
            // document.querySelector('h3').innerText = "哈哈1";
            // debugger;
            
        },
        mounted(){
            this.timer=setInterval(()=>{
                this.opacity -=0.01
                if(this.opacity<=0) this.opacity=1
            },1000)
            console.log("mounted");
            // console.log("this:",this);
            // document.querySelector('h3').innerText = "哈哈2";
            // debugger;
        },
        beforeUpdate(){
            console.log("mounted");
            
            // console.log("this.n:",this.n)
            // debugger;
        },
        updated(){
            console.log("updated")
            // console.log("this.n:",this.n)
            // debugger;
        },
        beforeDestroy(){
            clearInterval(this.timer)
            console.log("beforeDestroy")
            console.log(this.n)
            this.add()
            console.log("n:",this.n)
        },
        destroyed(){
            console.log("destroy")
        }
        //Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)
        // mounted(){
        //     setInterval(()=>{
        //         this.opacity -=0.01
        //         if(this.opacity<=0) this.opacity=1
        //     },16)
        // }
    })
</script>
</html>
View Code
posted @ 2023-02-19 17:43  codeing123  阅读(917)  评论(0编辑  收藏  举报