1. 程式人生 > >聊一聊Vue實例與生命周期運行機制

聊一聊Vue實例與生命周期運行機制

思維 mod images mic import mvvm 方法 add char

Vue的實例是Vue框架的入口,擔任MVVM中的ViewModel角色,所有功能的實現都是圍繞其生命周期進行的,在生命周期的不同階段調用對應的鉤子函數可以實現組件數據管理和DOM渲染兩大重要功能。例如,實例需要配置數據觀測(data observer)、編譯模版、掛載實例到 DOM ,然後在數據變化時更新 DOM 。在這個過程中,事件鉤子可以輔助我們對整個實例生成、編譯、掛載、銷毀等過程進行js控制,給我們提供了執行自定義邏輯的機會。所以學習實例的生命周期,能幫助我們理解vue實例的運行機制,更好地利用鉤子函數完成我們的業務代碼。

生命周期概覽

  技術分享

  

Vue提供的可以註冊的鉤子都在上圖片的紅色框標註。 它們分別是:

  • beforeCreate

在實例初始化之後,數據觀測(data observer) 和 event/watcher 事件配置之前被調用。此時的數據觀察和事件機制都未形成。

  • created

實例已經創建完成之後同步調用,此時實例已經結束解析選項。在這一步,實例已完成以下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調,此時this便指向vue實例。然而,掛載階段還沒開始,還沒有開始DOM編譯,$el 屬性目前不可見。

  • beforeMount

在掛載開始之前被調用:相關的 render 函數首次被調用。

  • mounted

el 被新創建的 vm.$el 替換,並掛載到實例上去之後調用該鉤子。如果 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。

  • beforeUpdate

數據更新時調用,發生在虛擬 DOM 重新渲染和打補丁之前。 你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。

  • updated

由於數據更改導致的虛擬 DOM 重新渲染和打補丁,在這之後會調用該鉤子。

當這個鉤子被調用時,組件 DOM 已經更新,所以你現在可以執行依賴於 DOM 的操作。然而在大多數情況下,你應該避免在此期間更改狀態,因為這可能會導致更新無限循環。

該鉤子在服務器端渲染期間不被調用。

  • beforeDestroy

實例銷毀之前調用。在這一步,實例仍然完全可用。

  • destroyed

Vue 實例銷毀後調用。調用後,Vue 實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。 該鉤子在服務器端渲染期間不被調用。

接下來做一個例子,看一下所有的生命周期具體執行時序是怎麽樣的

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <title>Vue實例與生命周期</title>
 6     <script type="text/javascript" src="https://unpkg.com/vue/dist/vue.js"></script>
 7 </head>
 8 <body>
 9 
10 <div id="app">
11     <p>{{ message }}</p>
12 </div>
13 
14 <script type="text/javascript">
15 
16     var app = new Vue({
17         el: #app,
18         data: {
19             message : "Vue實例與生命周期"
20         },
21         beforeCreate: function () {
22             console.group(beforeCreate 創建前狀態===============》);
23             console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
24             console.log("%c%s", "color:red","data   : " + this.$data); //undefined
25             console.log("%c%s", "color:red","message: " + this.message)
26         },
27         created: function () {
28             console.group(created 創建完畢狀態===============》);
29             console.log("%c%s", "color:red","el     : " + this.$el); //undefined
30             console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
31             console.log("%c%s", "color:red","message: " + this.message); //已被初始化
32         },
33         beforeMount: function () {
34             console.group(beforeMount 掛載前狀態===============》);
35             console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
36             console.log(this.$el);
37             console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
38             console.log("%c%s", "color:red","message: " + this.message); //已被初始化
39         },
40         mounted: function () {
41             console.group(mounted 掛載結束狀態===============》);
42             console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
43             console.log(this.$el);
44             console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
45             console.log("%c%s", "color:red","message: " + this.message); //已被初始化
46         },
47         beforeUpdate: function () {
48             console.group(beforeUpdate 更新前狀態===============》);
49             console.log("%c%s", "color:red","el     : " + this.$el);
50             console.log(this.$el);
51             console.log("%c%s", "color:red","data   : " + this.$data);
52             console.log("%c%s", "color:red","message: " + this.message);
53         },
54         updated: function () {
55             console.group(updated 更新完成狀態===============》);
56             console.log("%c%s", "color:red","el     : " + this.$el);
57             console.log(this.$el);
58             console.log("%c%s", "color:red","data   : " + this.$data);
59             console.log("%c%s", "color:red","message: " + this.message);
60         },
61         beforeDestroy: function () {
62             console.group(beforeDestroy 銷毀前狀態===============》);
63             console.log("%c%s", "color:red","el     : " + this.$el);
64             console.log(this.$el);
65             console.log("%c%s", "color:red","data   : " + this.$data);
66             console.log("%c%s", "color:red","message: " + this.message);
67         },
68         destroyed: function () {
69             console.group(destroyed 銷毀完成狀態===============》);
70             console.log("%c%s", "color:red","el     : " + this.$el);
71             console.log(this.$el);
72             console.log("%c%s", "color:red","data   : " + this.$data);
73             console.log("%c%s", "color:red","message: " + this.message)
74         }
75     })
76 </script>
77 </body>
78 </html>

運行代碼,在chrome console查看構造信息

技術分享

在console裏面執行一下更新操作,data的值被修改後將會觸發update操作。

  技術分享

執行實例銷毀,將會觸發destroy動作。如果後續依然想對實例進行其他操作,將會發現實例已經被銷毀,操作不會成功。

  技術分享

從上面的代碼和生命周期圖解可以看到,Vue的實例封裝很符合開發者的思維規範,生命周期非常清晰,是一款相當相當簡潔強大優雅的框架,很值得我們研究學習使用。

好了,vue的生命周期就介紹到這兒,歡迎大家留言交流;喜歡或有幫助到您的話,點個贊或推薦支持一下,謝謝!

聊一聊Vue實例與生命周期運行機制