每一個 Vue 實例在被建立時都要通過一系列的初始化過程——例如,須要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程當中也會運行一些叫作生命週期鉤子的函數,這給了用戶在不一樣階段添加本身的代碼的機會。javascript
好比 created
鉤子能夠用來在一個實例被建立以後執行代碼:html
new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 實例 console.log('a is: ' + this.a) } }) // => "a is: 1"
也有一些其它的鉤子,在實例生命週期的不一樣階段被調用,如 mounted
、updated
和 destroyed
。生命週期鉤子的 this
上下文指向調用它的 Vue 實例。vue
不要在選項屬性或回調上使用箭頭函數,好比
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
。由於箭頭函數並無this
,this
會做爲變量一直向上級詞法做用域查找,直至找到爲止,常常致使Uncaught TypeError: Cannot read property of undefined
或Uncaught TypeError: this.myMethod is not a function
之類的錯誤。java
下圖展現了實例的生命週期。你不須要立馬弄明白全部的東西,不過隨着你的不斷學習和使用,它的參考價值會愈來愈高。ajax
<div id="app"> {{ msg }} </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { msg: 'hi vue' }, // 在實例初始化以後,數據觀測(data observer)和 event/watcher事件配置以前調用; beforeCreate: function () { console.log('beforeCreate') }, /* 在實例建立完成後當即調用 在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的用算,watch/event事件的回調。 然而掛載的階段還沒開始,$el 屬性目前不可見 */ created: function () { console.log('created') }, // 在掛載開始以前調用:相關渲染的函數首次被調用 beforeMount: function () { console.log('beforeMount') }, // el 被建立的vm.$el替換,掛載成功 mounted: function () { console.log('mounted') }, // 數據更新時調用 beforeUpdate: function () { console.log('beforeUpdate') }, // 組件dom已經更新, 組件更新完畢 updated: function () { console.log('updated') } }); // 設置過時時間 setTimeout(function () { vm.$data.msg = "change ....." }, 3000); </script>
生命週期更多參數查看:https://cn.vuejs.org/v2/api/#beforeCreateapi
類型:Function
緩存
詳細:服務器
在實例初始化以後,數據觀測 (data observer) 和 event/watcher 事件配置以前被調用。app
參考:生命週期圖示dom
類型:Function
詳細:
在實例建立完成後被當即調用。在這一步,實例已完成如下的配置:數據觀測 (data observer),屬性和方法的運算,watch/event 事件回調。然而,掛載階段還沒開始,$el
屬性目前不可見。
發送ajax 實現數據驅動視圖
參考:生命週期圖示
類型:Function
詳細:
在掛載開始以前被調用:相關的 render
函數首次被調用。
該鉤子在服務器端渲染期間不被調用。
參考:生命週期圖示
類型:Function
詳細:
el
被新建立的 vm.$el
替換,並掛載到實例上去以後調用該鉤子。若是 root 實例掛載了一個文檔內元素,當 mounted
被調用時 vm.$el
也在文檔內。
虛擬dom Recat
獲取真實DOM
注意 mounted
不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染完畢,能夠用 vm.$nextTick 替換掉 mounted
:
mounted: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been rendered }) }
該鉤子在服務器端渲染期間不被調用。
參考:生命週期圖示
類型:Function
詳細:
數據更新時調用,發生在虛擬 DOM 打補丁以前。這裏適合在更新以前訪問現有的 DOM,好比手動移除已添加的事件監聽器。
該鉤子在服務器端渲染期間不被調用,由於只有初次渲染會在服務端進行。
參考:生命週期圖示
類型:Function
詳細:
因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。
當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。然而在大多數狀況下,你應該避免在此期間更改狀態。若是要相應狀態改變,一般最好使用計算屬性或 watcher 取而代之。
注意 updated
不會承諾全部的子組件也都一塊兒被重繪。若是你但願等到整個視圖都重繪完畢,能夠用 vm.$nextTick 替換掉 updated
:
updated: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been re-rendered }) }
該鉤子在服務器端渲染期間不被調用。
參考:生命週期圖示
類型:Function
詳細:
keep-alive 組件激活時調用。
該鉤子在服務器端渲染期間不被調用。
參考:
keep-alive 讓組件產生緩存
類型:Function
詳細:
keep-alive 組件停用時調用。
該鉤子在服務器端渲染期間不被調用。
參考:
類型:Function
詳細:
實例銷燬以前調用。在這一步,實例仍然徹底可用。
該鉤子在服務器端渲染期間不被調用。
參考:生命週期圖示
類型:Function
詳細:
Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
關閉定時器
該鉤子在服務器端渲染期間不被調用。
參考:生命週期圖示
2.5.0+ 新增
類型:(err: Error, vm: Component, info: string) => ?boolean
詳細:
當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子能夠返回 false
以阻止該錯誤繼續向上傳播。
你能夠在此鉤子中修改組件的狀態。所以在模板或渲染函數中設置其它內容的短路條件很是重要,它能夠防止當一個錯誤被捕獲時該組件進入一個無限的渲染循環。
錯誤傳播規則
config.errorHandler
被定義,全部的錯誤仍會發送它,所以這些錯誤仍然會向單一的分析服務的地方進行彙報。errorCaptured
鉤子,則它們將會被相同的錯誤逐個喚起。errorCaptured
鉤子自身拋出了一個錯誤,則這個新錯誤和本來被捕獲的錯誤都會發送給全局的 config.errorHandler
。errorCaptured
鉤子可以返回 false
以阻止錯誤繼續向上傳播。本質上是說「這個錯誤已經被搞定了且應該被忽略」。它會阻止其它任何會被這個錯誤喚起的 errorCaptured
鉤子和全局的 config.errorHandler
。beforeCreate(){ // 組件建立以前 console.log(this.msg); }, created(){ // 組件建立以後 // 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響 應用:發送ajax請求 console.log(this.msg); // this.msg = '嘿嘿黑'; }, beforeMount(){ // 裝載數據到DOM以前會調用 console.log(document.getElementById('app')); }, mounted(){ // 這個地方能夠操做DOM // 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM console.log(document.getElementById('app')); }, beforeUpdate(){ // 在更新以前,調用此鉤子,應用:獲取原始的DOM console.log(document.getElementById('app').innerHTML); }, updated(){ // 在更新以前,調用此鉤子,應用:獲取最新的DOM console.log(document.getElementById('app').innerHTML); }, beforeDestroy(){ console.log('beforeDestroy'); }, destroyed(){ console.log('destroyed'); }, activated(){ console.log('組件被激活了'); }, deactivated(){ console.log('組件被停用了'); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <App></App> </div> <script src="../vue.js"></script> <script> let Test = { data: function () { return { msg: 'alex', count: 0, timer: null } }, template: ` <div> <p>{{ count }}</p> <div id="box">{{ msg }}</div> <button v-on:click="changeHandler">修改</button> </div> `, methods: { changeHandler: function () { this.msg = 'wusir'; document.querySelector('#box').style.backgroundColor('red') } }, beforeCreate() { // 組件建立以前 console.log('組件建立以前', this.msg); }, created() { // 重要**** // 組件建立以後 // 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響 應用:發送ajax請求 console.log('組件建立以後', this.msg); this.timer = setInterval(() => { this.count++ }, 1000); // this.msg = '嘿嘿黑'; }, beforeMount() { // 裝載數據到DOM以前會調用 console.log(document.getElementById('app')); }, mounted() { // 這個地方能夠操做DOM // 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM console.log(document.getElementById('app')); }, beforeUpdate() { // 在更新以前,調用此鉤子,應用:獲取原始的DOM console.log(document.getElementById('app').innerHTML); }, updated() { // 在更新以前,調用此鉤子,應用:獲取最新的DOM console.log(document.getElementById('app').innerHTML); }, beforeDestroy() { console.log('beforeDestroy'); }, destroyed() { // 定時器的消耗在此方法處理 關閉清楚 console.log('destroyed',this.timer); clearInterval(this.timer); }, activated() { console.log('組件被激活了'); }, deactivated() { console.log('組件被停用了'); } }; let App = { data: function () { return { isShow: true } }, template: ` <div> <keep-alive> <Test v-if="isShow"/> </keep-alive> <button @click="clickRemove">改變test組件的生死</button> </div> `, methods: { clickRemove: function () { this.isShow = !this.isShow } }, components: { Test } }; let vm = new Vue({ el: '#app', data: function () { return {} }, components: { App } }) </script> </body> </html>