vue學習筆記(二)vue的生命週期和鉤子函式
前言
通過上一章的學習,我們已經初步的瞭解了vue到底是什麼東西,可以幹什麼,而這一篇部落格主要介紹vue的生命週期和它常用的鉤子函式,如果有學過java的園友可能有接觸到在學習servlet的時候學過servlet的生命週期servlet 載入--->例項化--->服務--->銷燬,對於vue的而言他也有自己的生命週期,那麼一起來看看吧!
本章目標
- 學會並瞭解vue的生命週期和鉤子函式
- 學會使用手動掛載和呼叫事件
vue的生命週期和鉤子函式
其實在提到vue的生命週期和鉤子函式的時候,有的人認為常用的鉤子函式有10個,也有的人認為是8個,無論是10個還是8個對於我而言都是一樣的,我們主要講解8個vue的鉤子函式。首先來一波官網的對於vue生命週期的圖解
這一張圖對於vue的生命週期已經講解的特別詳細了,但是光靠這一張圖還不足於瞭解它的生命週期,我們需要實踐一下,有句古話說的好,實踐是檢驗道理的唯一標準,介紹一下vue的鉤子函式。
beforeCreate(例項建立前)
例項元件剛開始建立,元素dom和資料都還沒有初始化
應用場景:可以在這加個loading事件
created(例項建立後)
資料data已經初始化完成,方法也已經可以呼叫,但是dom為渲染,在這個週期裡面如果進行請求是可以改變資料並渲染,由於dom未掛載,請求過多或者佔用時間過長會導致頁面線上空白
應用場景:在這結束loading,還做一些初始化,實現函式自執行
beforeMoute(元素掛載前)
dom未完成掛載,資料初始化完成,但是資料的雙向繫結還是{{}},這是因為vue採用了虛擬dom技術
mouted(元素掛載後)
資料和dom都完成掛載,在上一個週期佔位的資料把值渲染進去,一般請求會放在這個地方,因為這邊請求改變資料之後剛好能渲染
beforeUpdate(例項更新前)
只要是頁面資料改變了都會觸發,資料更新之前,頁面資料還是原來的資料,當你請求賦值一個數據的時候就會執行這個週期,如果沒有資料改變不執行
updated(例項更新後)
只要是頁面資料改變了都會觸發,資料更新完畢,頁面的資料是更新完成的,beforeUpdated和updated要謹慎使用,因為頁面更新資料的時候都會觸發,在這裡操作資料很影響效能和死迴圈
beforeDestory(例項銷燬前)
例項銷燬之前呼叫,在這一步,例項仍然完全可用
destory(例項銷燬後)
Vue例項銷燬後呼叫,呼叫後,Vue例項指示的所有內容都會解除繫結,所有的事件監聽器都會被移除,所有的子例項也會被銷燬
例項一
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue的生命週期例項一</title> </head> <body> <div id="app"> <input type="text" v-model="msg" /> {{msg}} </div> <button onclick="destory()">銷燬</button> <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const vm=new Vue({ el:'#app', data:{ msg:'vue' }, beforeCreate(){ console.log('vue例項建立前:'+this.msg+','+this.$el); // 資料data和dom都還沒有初始化 }, created(){ console.log('vue例項建立後:'+this.msg+','+this.$el); //資料dom初始化完成,dom還沒有初始化完成 }, beforeMount(){ console.log('元素掛載前:'); console.log(this.$el); }, mounted(){ console.log('元素掛載後:'); console.log(this.$el); }, beforeUpdate(){ console.log('例項更新前'); console.log(this.msg); console.log(this.$el); }, updated(){ console.log('例項更新後'); console.log(this.msg); console.log(this.$el); }, beforeDestroy(){ console.log('例項銷燬前'); console.log(this.msg); }, destroyed(){ console.log('例項銷燬後'); console.log(this.msg); } }); function destory(){ vm.$destroy(); } </script> </body> </html>
結果
例項二
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue的生命週期例項二</title> </head> <body> <div id="app"> {{name}} </div> <button onclick="destory()">銷燬例項</button> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const vm=new Vue({ el:'#app', data:{ name:'一隻流浪的kk', age:18 }, beforeCreate(){ console.log('============例項建立前============='); console.log(this.$el); //undefined console.log(this.$data);//undefined }, created(){ console.log('============例項建立後============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, beforeMount(){ console.log('============元素掛載前============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, mounted(){ console.log('============元素掛載後============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, beforeUpdate(){ console.log('============例項更新前============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, updated(){ console.log('============例項更新後============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, beforeDestroy(){ console.log('============例項銷燬前============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); }, destroyed(){ console.log('============例項銷燬後============='); console.log(this.$el); console.log(JSON.stringify(this.$data)); } }); function destory(){ vm.$destroy(); } </script> </body> </html>
總結
-
beforeCreate() : 此時$el、data 的值都為undefined,即el 和 data 並未初始化 。
-
create(): 此時可以拿到data的值,但是$el依舊為undefined,即data完成了 資料的初始化,el沒有。
-
beforeMounte(): $el的值為“虛擬”的元素節點,dom未完成掛載,資料初始化完成,但是資料的雙向繫結還是{{}},這是因為vue採用了虛擬dom技術。
-
mouted(): 資料和dom都完成掛載,在上一個週期佔位的資料把值渲染進去,一般請求會放在這個地方,因為這邊請求改變資料之後剛好能渲染。
vue例項的手動掛載和呼叫事件
vm.$mount( [elementOrSelector] ) 如果 Vue 例項在例項化時沒有收到 el 選項,則它處於“未掛載”狀態,沒有關聯的 DOM 元素。可以使用 vm.$mount() 手動地掛載一個未掛載的例項,學習手動掛載和呼叫事件之前,我提取了一些vue例項常用的屬性和方法,帶有字首 $ 便於與代理的data區分
- vm.$el:型別(HTMLElement)掛載元素,Vue例項的DOM根元素;即vm.$el===document.getElementById('節點'),注意:相等的情況必須是例項建立之後才行,也就是created之後。
- vm.$data:型別(Object),Vue例項觀察的資料物件
- vm.$props:型別(Object),當前元件接收到的 props 物件。Vue 例項代理了對其 props 物件屬性的訪問
- vm.$options:型別(Object),用於當前 Vue 例項的初始化選項。需要在選項中包含自定義屬性時會有用處
- vm.$parent:型別(Vue例項),父例項,如果當前例項有的話
- vm.$root:型別(Vue例項),當前元件樹的根 Vue 例項。如果當前例項沒有父例項,此例項將會是其自己
- vm.$children:型別(Array(Vue例項)),當前例項的直接子元件。需要注意
$children
並不保證順序,也不是響應式的。如果你發現自己正在嘗試使用$children
來進行資料繫結,考慮使用一個數組配合v-for
來生成子元件,並且使用 Array 作為真正的來源
官網地址:https://cn.vuejs.org/v2/api/
接下來是介紹手動掛載和呼叫事件的常用方法,共有三個
var MyComponent = Vue.extend({ template: '<div>Hello!</div>' }) // 建立並掛載到 #app (會替換 #app) new MyComponent().$mount('#app') // 同上 new MyComponent({ el: '#app' }) // 或者,在文件之外渲染並且隨後掛載 var component = new MyComponent().$mount() document.getElementById('app').appendChild(component.$el)
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>手動掛載和呼叫事件</title> </head> <body> <div id="app"> </div> <button onclick="hanlderOne()">手動掛載方式一</button> <button onclick="hanlderTwo()">手動掛載方式二</button> <button onclick="hanlderThree()">手動掛載方式三</button> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> const vm=new Vue({ data:{ name:'vue' }, template:'<h2>{{name}}</h2>' }) function hanlderOne(){ //方法一,手動掛載到指定的dom vm.$mount("#app"); } function hanlderTwo(){ //手動掛載,觸發編譯 vm.$mount(); document.getElementById('app').appendChild(vm.$el); } function hanlderThree(){ //擴充套件一個新的vue構造器 const component=Vue.extend({ template:'<h2>{{name}}</h2>' }); const a=new component({ data:{ name:'vue' }, el:'#app' }) } </script> </body> </html>
結果:
vm.$destroy() 完全銷燬一個例項。清理它與其它例項的連線,解綁它的全部指令及事件監聽器,這個方法我們在示例中有使用過,大家可以檢視前面的示