Vue生命週期(11個鉤子函數)

Vue生命週期

生命週期初識


生命週期圖.png

生命週期詳解(八個鉤子函數)

生命週期函數文字.png

  • 生命週期

生命週期: Vue是一個構造函數,當執行執行這個函數時,相當於初始化vue實例;
在創建實例過程中,需要設置數據監聽,編譯模板,將實例掛載到DOM上,數據更新能夠讓DOM也更新,
在這個初始化,又會不同階段默認調用一些函數執行,這些函數就是生命週期的鉤子函數;

  • 生命週期鉤子函數

生命週期鉤子函數,讓夠讓咱們在初始化實例時,添加自己的代碼;
生命週期的鉤子函數中的this,會默認指向vue的實例;

  • 鉤子函數

beforeCreate created[可以獲取數據及方法]
beforeMount mounted[可以獲取到真實的DOM]
beforeUpdate updated[數據更新執行]
beforeDestroy destroyed[銷燬vue實例,不再具有雙向數據綁定的特點]

生命週期圖.jpg

<body>
    <div id="app">
        <div>
            {{msg}}
        </div>
        <ul>
            <li v-for="a in arr"></li>
        </ul>
        <button @click="fn">點我一下</button>
    </div>
    <script src="../node_modules/axios/dist/axios.js"></script>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // 生命週期: Vue是一個構造函數,當執行執行這個函數時,相當於初始化vue實例;
      在創建實例過程中,需要設置數據監聽,編譯模板,將實例掛載到DOM上,數據更新能夠讓DOM也更新,
在這個初始化,又會不同階段默認調用一些函數執行,這些函數就是生命週期的鉤子函數;

        // 生命週期鉤子函數,讓夠讓咱們在初始化實例時,添加自己的代碼;
        //生命週期的鉤子函數中的this,會默認指向vue的實例
        // beforeCreate   created 
        // beforeMount    mounted
        // beforeUpdate   updated
        // beforeDestroy  destroyed
        //    function Vue(options){
        //         let a = document.querySelector(options.el);
        //         for(let key in options.data){
        //             Object.defineProperty(options.data,key,{
        //                 get(){

        //                 },
        //                 set(){

        //                 }
        //             })
        //         }
        //    }
        //     new Vue({el:"#app",data:{}})


        let vm = new Vue({
            data: {
                msg: "hello",
                arr: [1, 2, 3, 4]
            },
            // 1. 在這個鉤子函數執行之前初始化事件以及生命週期
            beforeCreate() {
                // 1. 在這個鉤子函數中,不能獲取data中的數據
                // console.log(this.msg);
                // 2. 這個函數不能操作DOM;
                // console.log(document.getElementsByTagName("li"))
            },
            // 給Vue的實例注入數據,進行數據監聽
            created() {
                // 在created發送請求
                // 1. 可以獲取到data中的數據
                // 2. 不能操作DOM的
                //console.log(this.msg);
                // console.log(document.getElementsByTagName("li"))

                axios.get("./carts.json").then(data => {
                    // 異步的;
                    this.arr = data.data;
                    console.log(2);

                })
            },
            methods: {
                getData() {

                },
                fn() {
                    this.msg = "world"
                }
            },
            // 執行之前,判斷是否有el,template;編譯
            beforeMount() {
                // console.log(document.getElementsByTagName("li"))
            },
            // 掛載完畢
            mounted() {
                // debugger
                // 掛載: 把VUE實例生成的虛擬的DOM轉成真實的DOM,放在了頁面中,這就是掛載;
                // 編譯出的DOM把原有的DOM替換完畢;
                // 可以獲取最終的DOM元素
                // let d = {type:"div",a:"1",chidlren:[{type:"span",children:[]}]}
                console.log(document.getElementsByTagName("li"));
                //console.log("mounted","初始化");
            },
            // 當數據更新時,會調用beforeUpdate 和updated鉤子函數;上面四個不再運行
            beforeUpdate() {
                console.log("beforeUpdate", "更新之前");
                console.log(this.msg)
                // 更新數據之前執行
            },
            updated() {
                console.log("beforeUpdate", "更新之後");
                // 數據更新,虛擬的DOM更新,然後更新真實的DOM;最後觸發這個函數
            },
            // 銷燬之前
            beforeDestroy() {
                // 銷燬之前
                // 清除定時器
                console.log("beforeDestroy");

            },
            // 銷燬之後
            destroyed() {
                console.log("destroyed");
                // 銷燬子組件,銷燬觀察者,事件監聽者
                // 元素的事件還在,但是更改數據不會再讓視圖進行更新了;
            }
        }).$mount("#app");
        // vm.$destroy();
        // console.log(vm);
        // 在項目中,你遇到過什麼問題,怎麼解決的?
        // 準備
    </script>
</body>

</html>

Vue的DOM異步渲染

<body>
    <div id="app">
        <ul>
            <li v-for="a in arr">{{a}}</li>
        </ul>
        {{sum}}
    </div>
    <script src="../node_modules/axios/dist/axios.js"></script>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            data:{
                 arr:[1,2,3]
            },
            created(){
                // 此時並沒有編譯模板
// 如果在created改變數據,那麼編譯進行一次;如果在mounted中改數據,會再次編譯模板;
                console.log(100);
            },
            beforeMount(){ 
                console.log(200);
//this.arr=[1,2,3,4];// 開始編譯模板編譯原有數據編譯3個li,存在內存中,
當數據更新時,立即將內存中的模板編譯成4li;最後掛載到真實的DOM上;不會引發beforeUpdate函數的調用
            },
            computed:{
                sum(){
                    // 在掛載的過程中,執行的這個函數
                    console.log(1);
                    return 100;
                }
            },
            // 編譯模板
            // 在mounted之前改數據,不會調用beforeUpdate這個函數;
            // DOM 已經掛載完畢
            mounted(){
                console.log(300);
                this.arr=[1,2,3,4];
// 開始編譯模板編譯原有數據編譯3個li,存在內存中,並且直接掛載到了真實DOM中,當數據更新時,
立即將內存中的模板編譯成4li;再次把最新掛載到真實的DOM上;會引發beforeUpdate函數的調用
// VUE中DOM的更新是異步的;
// 如何在mounted中操作最新的DOM呢?
// $nextTick需要傳入一個回調函數,會當真實的DOM再次更新完成,會立即調用這個回調函數;
                this.$nextTick(()=>{
                    let oLis = document.getElementsByTagName("li")
                    console.log(oLis.length);
                });
            },
            beforeUpdate(){
                console.log("beforeUpdate");
            }
        }).$mount("#app");
    </script>
</body>
</html>

生命週期(其他三個鉤子函數)

component 和keep-alive

  • component 和keep-alive 都是內置組件,在VUE代碼已經內置好的組件;
    • 閉合標籤使用組件

component : 內置組件,根據is屬性來顯示對應的組件;is屬性的屬性值保持和組件名字一致;然後可以顯示對應的組件

component: 每次能動態顯示一個組件,當切換下一個組件時,當前組件要銷燬
<component is=“second”>

  • keep-alive : keep: 保持 alive:活力

VUE項目的優化: keep-alive

  • keep-alive : keep: 保持 alive:活力
    <keep-alive>
    keep-alive:用於緩存組件,如果該組件還會再啓用,那麼可以使用keep-alive進行組件緩存和優化,提高性能,緩存的組件不需要銷燬,也不需要再創建
    <component v-bind:is=“one”> //如果是動態屬性,那麼會去data中取值
    </keep-alive>

三個鉤子函數詳解

  • 當keep-alive 緩存組件纔會有的生命週期的鉤子函數
    • activated deactivated
  • errorCaptured 當子孫組件出錯時,會調用這個鉤子函數

// keep-alive 緩存組件 生命週期的鉤子函數 activated deactivated
// 生命週期的鉤子函數
activated() {
// 當緩存組件有被顯示出來時,會觸發這個鉤子函數
console.log(100);
},
deactivated() {
// 當緩存的組件隱藏時,會觸發這個鉤子函數;
console.log(200);
},
// 當子孫組件出錯時,會調用這個鉤子函數
errorCaptured(a, b, c) {
// 當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
console.log(a);
console.log(b);
console.log©;
console.log(“子組件報錯”)
},

<body>
    <div id="app">
        <button @click="fn">點一點</button>
        <!-- // component : 內置組件,根據is屬性來顯示對應的組件;
    is屬性的屬性值保持和組件名字一致;然後可以顯示對應的組件
        // 如果是動態屬性,那麼會去data中取值 -->
        <!-- <component is="second"></component> -->
        <keep-alive>
            <!-- keep-alive:用於緩存組件,如果該組件還會再啓用,
            那麼可以使用keep-alive進行組件緩存和優化,提高性能,緩存的組件不需要銷燬,
也不需要再創建 -->
            <component v-bind:is="one"></component>
        </keep-alive>

    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        // component 和keep-alive 都是內置組件,在VUE代碼已經內置好的組件;
        // 閉合標籤使用組件
        // component: 每次能動態顯示一個組件,當切換下一個組件時,當前組件要銷燬
        // keep-alive : keep: 保持  alive:活力 
        // VUE項目的優化: keep-alive
        let kkk = {
            data() {
                return {
                    a: cc
                }
            },
            template: "<div>{{a}}</div>"
        }
        let first = {
            destroyed() {
                console.log("銷燬")
            },
            components: {
                kkk
            },
            // keep-alive 緩存組件 生命週期的鉤子函數  activated  deactivated
            // 生命週期的鉤子函數
            activated() {
                // 當緩存組件有被顯示出來時,會觸發這個鉤子函數
                console.log(100);
            },
            deactivated() {
                // 當緩存的組件隱藏時,會觸發這個鉤子函數;
                console.log(200);
            },
            // 當子孫組件出錯時,會調用這個鉤子函數
            errorCaptured(a, b, c) {
                // 當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、
發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
                console.log(a);
                console.log(b);
                console.log(c);
                console.log("子組件報錯")
            },
            template: "<div>我是老大<kkk></kkk></div>"
        };
        let second = {
            template: "<div>我是老二</div>"
        }
        let third = {
            template: "<div>我是老三</div>"
        }
        let vm = new Vue({
            el: "#app",
            data: {
                one: "first"
            },
            methods: {
                fn() {
                    let ary = ["first", "second", "third"];
                    let index = ary.indexOf(this.one);
                    if (index < 2) {
                        this.one = ary[index + 1];
                    } else {
                        this.one = ary[0];
                    }
                    // 
                    // switch (this.one) {
                    //     case "first":
                    //         this.one = "second"
                    //         break;
                    //     case "second":
                    //         this.one = "third"
                    //         break;
                    //     default:
                    //         this.one = "first"
                    //         break;
                    // }
                }
            },
            components: {
                first,
                second,
                third
            },

        });
    </script>
</body>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章