最近在寫業務的時候,老是會遇到一些和vue的生命週期相關的問題,好比: 你用ajax請求數據,而後將數據props到子組件的時候,由於ajax是異步的,而後會發生沒有數據。而後查找緣由仍是本身對這個東西理解不夠深刻。html
什麼是生命週期函數?vue
好比:react
mounted: function() {
}
// 或者
mounted() {
}
複製代碼
錯誤的形式:ajax
mounted:() => {
}
複製代碼
實例初始化——new Vue()
bash
數據觀測——在vue的響應式系統中加入data對象中全部數據,這邊涉及到vue的雙向綁定,能夠看官方文檔上的這篇深度響應式原理 深度響應式原理app
暴露屬性和方法——就是vue實例自帶的一些屬性和方法,咱們能夠看一個官網的例子,例子中帶$的屬性和方法就是vue實例自帶的,能夠和用戶定義的區分開來異步
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一個實例方法
vm.$watch('a', function (newValue, oldValue) {
// 這個回調將在 `vm.a` 改變後調用
})
複製代碼
// 有el屬性的狀況下
new Vue({
el: '#app',
beforeCreate: function() {
console.log('調用了beforeCreate')
},
created: function() {
console.log('調用了created')
},
beforeMount: function() {
console.log('調用了beforeMount')
},
mounted: function() {
console.log('調用了mounted')
}
})
// 輸出結果
// 調用了beforeCreate
// 調用了created
// 調用了beforeMount
// 調用了mounted
複製代碼
// 在沒有el屬性的狀況下,沒有vm.$mount
new Vue({
beforeCreate: function() {
console.log('調用了beforeCreate')
},
created: function() {
console.log('調用了created')
},
beforeMount: function() {
console.log('調用了beforeMount')
},
mounted: function() {
console.log('調用了mounted')
}
})
// 輸出結果
// 調用了beforeCreate
// 調用了created
複製代碼
// 在沒有el屬性的狀況下,可是有vm.$mount方法
var vm = new Vue({
beforeCreate: function() {
console.log('調用了beforeCreate')
},
created: function() {
console.log('調用了created')
},
beforeMount: function() {
console.log('調用了beforeMount')
},
mounted: function() {
console.log('調用了mounted')
}
})
vm.$mount('#app')
// 輸出結果
// 調用了beforeCreate
// 調用了created
// 調用了beforeMount
// 調用了mounted
複製代碼
這裏面分三種狀況:ide
一、在實例內部有template屬性的時候,直接用內部的,而後調用render函數去渲染。 二、在實例內部沒有找到template,就調用外部的html。實例內部的template屬性比外部的優先級高。 三、要是前二者都不知足,那麼就拋出錯誤。函數
咱們來看如下幾個例子:ui
new Vue({
el: '#app',
template: '<div id="app">hello world</div>'
})
//頁面上渲染出了hello world
複製代碼
<div id="app">hello world</div>
new Vue({
el: '#app'
})
// 頁面上渲染出了hello world
複製代碼
//二者都存在的時候
<div id="app">hello world2</div>
new Vue({
el: '#app',
template: '<div id="app">hello world1</div>'
})
// 頁面上渲染出了hello world1
複製代碼
從上述的例子能夠看出內部的優先外部的。
一、爲何el屬性的判斷在template以前? 由於el是一個選擇器,好比上述例子中咱們用到的最多的是id選擇器app,vue實例須要用這個el去template中尋找對應的。
二、實際上,vue實例中還有一種render選項,咱們能夠從文檔上看一下他的用法:
new Vue({
el: '#app',
render() {
return (...)
}
})
複製代碼
三、上述三者的渲染優先級:render函數 > template屬性 > 外部html
四、vue編譯過程——把tempalte編譯成render函數的過程。
咱們先來看一個例子:
<div id="app">
<p>{{message}}</p>
</div>
new Vue({
el: '#app',
data: {
message: 1
},
beforeMount: function() {
console.log('調用了beforeMount');
console.log(this.message)
console.log(this.$el)
},
mounted: function() {
console.log('調用了mounted');
console.log(this.message)
console.log(this.$el)
}
})
// 輸出的結果:
// 調用了beforeMount
// 1
// <div>
// </div>
// 調用了mounted
// 1
// <div id="app">
// <p>1</p>
// </div>
複製代碼
建立vue實例的$el,而後用它替代el屬性。
這個過程當中,咱們會發現,當一個數據發生改變時,你的視圖也將隨之改變,整個更新的過程是:數據改變——致使虛擬DOM的改變——調用這兩個生命鉤子去改變視圖
// 沒綁定的狀況
var vm = new Vue({
el: '#app',
template: '<div id="app"></div>',
beforeUpdate: function() {
console.log('調用了beforeUpdate')
},
updated: function() {
console.log('調用了uodated')
},
data: {
a: 1
}
})
vm.a = 2
//這種狀況在控制檯中是什麼都不會輸出的。
複製代碼
var vm = new Vue({
el: '#app',
template: '<div id="app">{{a}}</div>',
beforeUpdate: function() {
console.log('調用了beforeUpdate')
},
updated: function() {
console.log('調用了uodated')
},
data: {
a: 1
}
})
vm.a = 2
// 輸出結果:
// 調用了beforeUpdate
// 調用了uodated
複製代碼
在beferoDestory生命鉤子調用以前,全部實例均可以用,可是當調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
let vm = new Vue({
el: '#app',
data: {
message: 1
},
template: '<div id="app"><p>{{message}}</p></div>',
beforeCreate() {
console.log('調用了beforeCreate')
console.log(this.message)
console.log(this.$el)
},
created() {
console.log('調用了created')
console.log(this.message)
console.log(this.$el)
},
beforeMount() {
console.log('調用了beforeMount')
console.log(this.message)
console.log(this.$el)
},
mounted() {
console.log('調用了mounted')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate() {
console.log('調用了beforeUpdate')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('調用了updated')
console.log(this.message)
console.log(this.$el)
},
beforeDestory() {
console.log('調用了beforeDestory')
console.log(this.message)
console.log(this.$el)
},
destoryed() {
console.log('調用了Destoryed')
console.log(this.message)
console.log(this.$el)
}
})
vm.message = 2
複製代碼
// 調用了beforeCreate
// undefined
// undefined
// 調用了created
// 1
// undefined
// 調用了beforeMount
// 1
// <div></div>
// 調用了mounted
// 1
// <div id="app"><p>1</p></div>
// 調用了beforeUpdate
// 2
// <div id="app"><p>2</p></div>
// 調用了updated
// 2
// <div id="app"><p>2</p></div>
複製代碼