下一篇:Vue組件通訊深刻javascript
這篇博客將會從下面四個常見的應用詮釋組件的生命週期,以及各個生命週期應該幹什麼事html
建議:博客中的例子都放在vue_blog_project工程中,推薦結合工程實例與博客一同窗習vue
生命週期:Vue 實例從開始建立、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,咱們稱這是 Vue 的生命週期,各個階段有相對應的事件鉤子
下面這張圖是vue生命週期各個階段的執行狀況:java
生命週期鉤子 | 組件狀態 | 最佳實踐 |
---|---|---|
beforeCreate | 實例初始化以後,this指向建立的實例,不能訪問到data、computed、watch、methods上的方法和數據 | 經常使用於初始化非響應式變量 |
created | 實例建立完成,可訪問data、computed、watch、methods上的方法和數據,未掛載到DOM,不能訪問到$el屬性,$ref屬性內容爲空數組 | 經常使用於簡單的ajax請求,頁面的初始化 |
beforeMount | 在掛載開始以前被調用,beforeMount以前,會找到對應的template,並編譯成render函數 | - |
mounted | 實例掛載到DOM上,此時能夠經過DOM API獲取到DOM節點,$ref屬性能夠訪問 | 經常使用於獲取VNode信息和操做,ajax請求 |
beforeupdate | 響應式數據更新時調用,發生在虛擬DOM打補丁以前 | 適合在更新以前訪問現有的DOM,好比手動移除已添加的事件監聽器 |
updated | 虛擬 DOM 從新渲染和打補丁以後調用,組件DOM已經更新,可執行依賴於DOM的操做 | 避免在這個鉤子函數中操做數據,可能陷入死循環 |
beforeDestroy | 實例銷燬以前調用。這一步,實例仍然徹底可用,this仍能獲取到實例 | 經常使用於銷燬定時器、解綁全局事件、銷燬插件對象等操做 |
destroyed | 實例銷燬後調用,調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬 | - |
注意:git
mounted
不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染完畢,能夠用 vm.$nextTick 現根據實際代碼執行狀況分析:github
<template> <div> <h3>單組件</h3> <el-button @click="dataVar += 1">更新 {{dataVar}}</el-button> <el-button @click="handleDestroy">銷燬</el-button> </div> </template>
export default { data() { return { dataVar: 1 } }, beforeCreate() { this.compName = 'single' console.log(`--${this.compName}--beforeCreate`) }, created() { console.log(`--${this.compName}--created`) }, beforeMount() { console.log(`--${this.compName}--beforeMount`) }, mounted() { console.log(`--${this.compName}--mounted`) }, beforeUpdate() { console.log(`--${this.compName}--beforeUpdate`) }, updated() { console.log(`--${this.compName}--updated`) }, beforeDestroy() { console.log(`--${this.compName}--beforeDestroy`) }, destroyed() { console.log(`--${this.compName}--destroyed`) }, methods: { handleDestroy() { this.$destroy() } } }
初始化組件時,打印:ajax
當data中的值變化時,打印:segmentfault
當組件銷燬時,打印:api
從打印結果能夠看出:數組
將單組件做爲基礎組件(因爲props在beforeCreate()中未初始化),須要作以下更改:
props: { compName: { type: String, default: 'single' } }, beforeCreate() { // this.compName = 'single' // console.log(`--${this.compName}--beforeCreate`) console.log(` --data未初始化--beforeCreate`) },
父組件代碼以下:
<template> <div class="complex"> <h3>複雜組件</h3> <lifecycle-single compName="child"></lifecycle-single> </div> </template>
const COMPONENT_NAME = 'complex' import LifecycleSingle from './LifeCycleSingle' export default { beforeCreate() { console.log(`--${COMPONENT_NAME}--beforeCreate`) }, created() { console.log(`--${COMPONENT_NAME}--created`) }, beforeMount() { console.log(`--${COMPONENT_NAME}--beforeMount`) }, mounted() { console.log(`--${COMPONENT_NAME}--mounted`) }, beforeUpdate() { console.log(`--${COMPONENT_NAME}--beforeUpdate`) }, updated() { console.log(`--${COMPONENT_NAME}--updated`) }, beforeDestroy() { console.log(`--${COMPONENT_NAME}--beforeDestroy`) }, destroyed() { console.log(`--${COMPONENT_NAME}--destroyed`) }, components: { LifecycleSingle } }
初始化組件時,打印:
當子組件data中的值變化時,打印:
當父組件data中的值變化時,打印:
當props改變時,打印:
當子組件銷燬時,打印:
當父組件銷燬時,打印:
從打印結果能夠看出:
在上面的基礎上,複雜組件作以下更改
<template> <div class="complex"> <h3>複雜組件</h3> <lifecycle-single compName="cihld1"></lifecycle-single> <lifecycle-single compName="child2"></lifecycle-single> <el-button @click="dataVar += 1">complex更新 {{dataVar}}</el-button> <el-button @click="handleDestroy">complex銷燬</el-button> </div> </template>
初始化組件時,打印:
當child1更新和銷燬時,打印:
當child2更新和銷燬時,打印:
當父組件銷燬時,打印:
從打印結果能夠看出:
在上面的基礎上,添加一個mixin.js文件,內容以下:
const COMPONENT_NAME = 'lifecycleMixin' export default { name: COMPONENT_NAME, beforeCreate() { console.log(`--${COMPONENT_NAME}--beforeCreate`) }, created() { console.log(`--${COMPONENT_NAME}--created`) }, beforeMount() { console.log(`--${COMPONENT_NAME}--beforeMount`) }, mounted() { console.log(`--${COMPONENT_NAME}--mounted`) }, beforeUpdate() { console.log(`--${COMPONENT_NAME}--beforeUpdate`) }, updated() { console.log(`--${COMPONENT_NAME}--updated`) }, beforeDestroy() { console.log(`--${COMPONENT_NAME}--beforeDestroy`) }, destroyed() { console.log(`--${COMPONENT_NAME}--destroyed`) } }
一樣的,複雜組件作以下更改:
import lifecycleMixin from './mixin' export default { mixins: [lifecycleMixin], // ... }
組件初始化時,打印:
組件銷燬時,打印:
從打印結果能夠看出:
mixin中的生命週期與引入該組件的生命週期是僅僅關聯的,且mixin的生命週期優先執行
參考: