本文將對vue的生命週期進行詳細的講解,讓你瞭解一個vue實例的誕生都經歷了什麼~
我在Github上創建了一個存放vue筆記的倉庫,之後會陸續更新一些知識和項目中遇到的坑,有興趣的同窗能夠去看看哈(歡迎star)! vue
傳送門node
const app = new Vue({ el:"#app', data:{ message:'hello,lifePeriod' }, methods:{ init(){ console.log('這是一個方法!') } } })
組件實例剛被建立,此時沒法訪問到 el 屬性和 data 屬性等..git
beforeCreate(){ console.log(`元素:${this.$el}`) //undefined console.log(`屬性message:${this.message}`) //undefined console.log(`方法init:${this.init}`) //undefined }
當一個 vue 實例被建立時,他向 Vue 的響應式系統中加入了其 data 對象中能找到的全部屬性.github
利用 es5 特性 Object.defineProperty,遍歷 data 對象下全部屬性,將其轉化爲 getter/setter,以便攔截對象賦值與取值操做,而後利用發佈/訂閱者模式,從而實現數據的雙向綁定!web
因此只有當實例被建立時 data 中存在的屬性纔是響應式的!!!!算法
將methods 下的全部方法進行聲明.app
將methods下的方法和data下的屬性經過遍歷和利用 es5 特性 Object.defineProperty代理到實例下.dom
this.a = this.$data.a = this.data.a; this.fn = this.$methods.fn = this.methods.fn;
組件實例建立完成,屬性已綁定,但 DOM 還未生成,$el 屬性還不存在!函數
created(){ console.log(`元素:${this.$el}`) //undefined console.log(`屬性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
將模板 template 編譯成 AST 樹、render 函數(new Watch 將模板與數據創建聯繫)以及 staticRenderFns 函數(經過 diff 算法優化 dom 更新);
運行 render 方法,返回一個 vnode 對象(virtual dom)優化
模板編譯/掛載以前
beforeMount(){ console.log(`元素:${(this.$el)}`) console.log(this.$el) //<div id="app">{{message}}</div> ,咱們發現此時的el還未對數據進行渲染.(虛擬dom的內容) }
模板編譯/掛載以後
mounted(){ console.log(`元素:${(this.$el)}`) console.log(this.$el) //<div id="app">{{hello,vue-lifePeriod!}}</div> ,已將數據渲染到真實dom }
組件更新以前
beforeUpdate(){ console.log(this.$el.innerHTML); //hello,vue-lifePeriod ,此時,元素的真實dom內容還未改變. }
組件更新以後
updated(){ console.log(this.$el.innerHTML); //hey,vue-lifePeriod ,此時,元素的真實dom內容已經改變. }
組件銷燬以前
beforeDestroy(){ console.log(this.$el) //<div id="app">{{hey,vue-lifePeriod!}}</div> console.log(`屬性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
組件銷燬以後
destroyed(){ console.log(this.$el) //<div id="app">{{hey,vue-lifePeriod!}}</div> console.log(`屬性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
實例銷燬後雖然 dom 和屬性方法都還存在,但改變他們都將再也不生效!
app.message = 'hu,vue-lifePeriod';
console.log(app.message) //hey,vue-lifePeriod