測試程式碼:
<div id="app">
<h2>{{ msg }}</h2>
<button @click="init" type="button">點選</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: "hello word!"
},
methods: {
init () {
alert('init');
}
},
beforeCreate () {
console.log('======beforeCreate=====');
console.log(`el: ${this.$el}`);
console.log(`data: ${this.$data}`);
console.log(`init: ${this.init}`);
},
created () {
console.log('======created=====');
console.log(`el: ${this.$el}`);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
console.log(`init: ${this.init}`);
// this.$data.msg = '1111'; // 這是可以對資料進行更改,但是不會觸發update生名周期函式,所以一般會在這裡做資料請求
},
beforeMount (){
console.log('======beforeMount=====');
console.log(`el: ${this.$el}`);
console.log(this.$el);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
console.log(`init: ${this.init}`);
// 這裡不做任何事,同時也不能修改資料
},
mounted () {
console.log('======mounted=====');
console.log(`el: ${this.$el}`);
console.log(this.$el);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
console.log(`init: ${this.init}`);
},
beforeUpdate () {
console.log('======beforeUpdateupdated=====');
console.log(`el: ${this.$el.innerHTML}}`);
console.log(this.$el);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
console.log(`init: ${this.init}`);
},
updated () {
console.log('======updated=====');
console.log(`el: ${this.$el.innerHTML}`);
console.log(this.$el);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
console.log(`init: ${this.init}`);
},
beforeDestroy () {
console.log('======beforeDestroy=====');
console.log(`el: ${this.$el}`);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
},
destroyed () {
console.log('======destroyed=====');
console.log(`el: ${this.$el}`);
console.log(`data: ${this.$data}`);
console.log(`message: ${this.msg}`);
}
})
// vm.$mount(app);
</script>
複製程式碼
-
beforCreate 和 created之間
- 檢測data資料的變化,初始化事件。
- 這時候並沒有el
-
created
- 沒有el, Dom 沒有生成
-
created 和 beforMount之間
- 首先判斷是否有el選項,如果沒有暫時停止生命週期,直到手動執行vm.mount(el),有則繼續編譯過程,繼續執行
- 在判斷是否有template選項,如果沒有采用外部html模版,否則採用template選項編譯成render函式
- 這裡的render 指的是jsx寫法。
- 優先順序 render > template > 外部的html
- 在created時,是可以修改資料的,通常我們會在這裡向伺服器請求資料
-
==問題==:為什麼需要去判斷el 和 template 選項呢?
-
==結論==:首先我們需要el選擇器,否則生命週期會暫時被終止,到created就停止了,所以el選擇器為前提條件,必須在template之前,通過對應的el選擇器拿到相對應的template。對於template優先順序的問題,template編輯後都要轉換成render函式,更接近Vue解析器,接著就是vue例項中的template選項了,如果template和外部的html同時存在,那麼template優先順序高於外部的html
-
beforMount
- el、 data初始化,拿到了虛擬dom (virtual dom)這時的資料還未進行渲染,{{message}} 只是一個佔位符。
-
Mounted
- 渲染真實的Dom(適合操作dom)
-
beforeUpdate
- 此時,元素的真實dom內容還未改變
-
Updated
- 重新渲染虛擬 dom,並通過 diff 演算法對比 vnode 節點差異更新真實 dom
-
beforeDestroy
-
destroyed
- 例項銷燬後雖然 dom 和屬性方法都還存在,但改變他們都將不再生效!