vue這一生做了什麼?(通過實例瞭解vue生命週期)

前言


  • vue是一套用於構建用戶界面的漸進式框架,現已成爲 github 上 star 數量最多的前端框架,是三大主流框架之一。
  • 由於 vue 是漸進式框架,幫助我們減少不必要的 dom 操作,提高開發效率。使廣大前端開發者只需要關注業務邏輯,不再關心 dom 如何渲染。
  • 最主流的前端框架之一,你真的瞭解嗎?它的各個命週期都做了什麼?下文揭曉。

生命週期鉤子


每個 vue 實例都經過一系列初始化步驟,從創建時設置數據到編譯模板,將實例裝載到 DOM,最後在數據更改期間更新DOM,整個過程被稱爲 Vue 實例的聲明週期。

官網的生命週期流程圖:

關於每個鉤子函數裏組件的狀態實例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的生命週期</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h3>{{info}}</h3>
        <button v-on:click='updateInfo'>修改數據</button>
        <button v-on:click='destoryComponent'>銷燬組件</button>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                info: 'Vue的生命週期'
            },
            beforeCreate: function(){
                console.log("beforeCreated-組件創建前");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
            },
            created: function(){
                console.log("created-組件創建完畢");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            beforeMount: function(){
                console.log("beforeMounted-組件掛載前");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            mounted: function(){
                console.log("mounted-組件掛載完畢");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            beforeUpdate: function(){
                console.log("beforeUpdate-組件更新前");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            updated: function(){
                console.log("updated-組件更新完畢");
                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            beforeDestroy: function(){
                console.log("beforeDestory-組件銷燬前");

                //在組件銷燬前嘗試修改data中的數據
                this.info="組件銷燬前";

                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            destroyed: function(){
                console.log("destoryed-組件銷燬完畢");
                
                //在組件銷燬完畢後嘗試修改data中的數據
                this.info="組件已銷燬";

                console.log("el:");
                console.log(this.$el);
                console.log("data:");
                console.log(this.$data);
                console.log("info:");
                console.log(this.$data.info);
            },
            methods: {
                updateInfo: function(){
                    // 修改data數據
                    this.info = '我發生變化了'
                },
                destoryComponent: function(){
                    //手動調用銷燬組件
                    this.$destroy();
                   
                }
            }
        });
    </script>
</body>
</html>

創建Vue實例

  • Vue項目都是通過組件化進行實現的,一個頁面通過若干組件組成,構成一個組件樹。
  • 每個組件都通過一個 Vue 實例來管理。
  • 通過 new Vue() 創建實例,實例創建了一個vue 實例的空殼,初始化生命週期和事件

初始化階段–beforeCreate

這是在 Vue.js 中調用的第一個生命週期鉤子,它在vue實例初始化之後,組件創建前被調用。

打印結果:
在這裏插入圖片描述
組件創建前,組件需要掛載的DOM元素el和組件的數據data都未被創建。

從源碼中來看看 vue 都做了什麼?源碼地址

vm._self = vm
initLifecycle(vm)	//初始化生命週期,主要做一些屬性初始化
initEvents(vm)		//初始化事件,初始化父元素給子節點綁定的一些事件
initRender(vm)		//初始化 render 函數
callHook(vm, 'beforeCreate')

Tips:在 beforeCreate 中不要去修改 data 中賦值的數據,最早也要在 create 中去做。

初始化階段–created

  • 實例創建完成,完成數據的初始化
  • 可訪問 data computed watch methods 上的方法和數據
  • 不能訪問 el,爲 undefined

打印結果:
在這裏插入圖片描述
組件創建完畢,組件的數據已經創建成功,但是DOM元素el還沒被創建。

掛載階段–beforeMount

  • 頁面中的內容還是 vue 的佔位符,$el 屬性已存在,是虛擬DOM,只是數據未掛載到模板中

打印結果:
在這裏插入圖片描述
組件掛載前,DOM元素已經被創建,只是data中的數據還沒有應用到DOM元素上。

掛載階段–mounted

  • 完成創建vm
  • 完成 el 雙向綁定,完成掛載和DOM渲染,可以在這個階段對DOM進行操作

打印結果:
在這裏插入圖片描述
組件掛載完畢後,data中的數據已經成功應用到DOM元素上,此時,掛載階段已經結束。

更新狀態–beforeUpdate

  • 組件更新前,data數據已經更新,組件掛載的DOM元素的內容也已經同步更新。
  • 只有 view 上的數據變化纔會觸發 beforeUpdate 和 update ,僅屬於data 中的數據改變是並不能觸發的。

打印結果:
在這裏插入圖片描述

更新狀態–updated

  • 數據更新完成,dom 也已經 render 完成(render 可以完成渲染操作,是渲染函數)
  • 不要在此函數中操作數據,會陷入死循環的。
  • 大多數情況下應避免在此期間更新狀態,如有相應狀態要改變,通常最好使用 computed 和 watch 取而代之。

打印結果:
在這裏插入圖片描述
組件更新完畢後,data數據已經更新,組件掛載的DOM元素的內容也已經同步更新。

實例銷燬階段–beforeDestory

打印結果:
在這裏插入圖片描述
組件銷燬前,組件已經不再受vue管理,我們可以繼續更新數據,但是模板已經不再更新。

實例銷燬階段–destoryed

打印結果:
在這裏插入圖片描述

  • 組件銷燬完畢,vue實例指示的所有東西會解除,所有的事件監聽也會被移除,所有子實例也會被銷燬。
  • 執行 destory() 方法後,對 data 的改變不會再觸發周期函數,此時 vue 實例已經解除了事件監聽以及和 dom 的綁定,但 dom 結構依然存在。

最後


以上爲本人學習Vue 生命週期的總結,如有錯誤,望指正,不勝感激!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章