--- tags: Javascript, Vue --- # Vue生命週期筆記 每個Vue組件都會經過初始化的步驟,設置數據,編譯模板,掛載DOM等,稱為生命週期,Vue讓我們可以在特定階段添加我們自己所需的代碼,稱為`lifecycle hooks`,就是下面圖片紅色框框的。 Vue官方生命週期圖 ![](https://i.imgur.com/73vtIGm.png) ## lifecycle hooks ### beforeCreate **在實例初始化時調用。** 此階段在`props`後,但還取不到`data()`內的值,所以不能在這階段利用`axios`取得資料 ### created **在實例處理完所有與狀態相關的選項後調用。** 此階段已設置數據, 屬性, 方法, 觀察者,`vm.$el`屬性還無法使用,可以在這呼叫api取得初始化頁面資料 ### beforeMonut **安裝組件之前調用。** 當這個狀態被調用時,組件已經完成了它的反應狀態的設置,但是還沒有創建 `DOM` 節點,未與實體做綁定 ### mounted **安裝組件後調用。** 所有同步子組件安裝完成,但不包括非同步組件,如想等待View渲染完畢可以使用,可以在此狀態内部使用 `vm.$nextTick` ### beforeUpdate 當狀態更新時,即將更新`DOM`樹之前調用 ### updated 當狀態更新時,即將更新`DOM`樹之後調用,如要在此訪問更新後的`DOM`,請改用`nextTick()` ### beforeUnmount **在要卸載組件實例之前調用。** 調用時,組件實例還可以工作 ### unmounted **在組件卸載後調用。** 所有子組件已卸載,相關反應效果停止 ### activated 緩存的實例被啟動,搭配`<KeepAlive>`。 ### deactivated 緩存的實例被關閉,搭配`<KeepAlive>`。 ## 查看生命週期範例 利用子組件的安裝卸載查看生命週期。 ![](https://i.imgur.com/Roa9Tri.gif) ```html= <!DOCTYPE html> <html> <head> <title>生命週期</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charset="UTF-8" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.global.js"></script> </head> <body class="bg-lighter"> <div class="container main my-5"> <div class="row"> <main class="col post"> <div class="mb-4"> <h1 class="mt-0 text-muted">生命週期</h1> </div> <div id="app"> <button @click="isShowing = !isShowing" class="btn btn-primary"> <span v-if="isShowing">隱藏元件</span> <span v-else>顯示元件</span> </button> <hr /> <!-- <keep-alive> <component v-if="isShowing" is="child" /> </keep-alive> --> <child v-if="isShowing" :prop="'propText'"></child> </div> <script type="text/x-template" id="childarea"> <div> <h4>{{ text }}</h4> <input type="text" class="form-control" v-model="text"> </div> </script> <script> const child = { template: "#childarea", data: function () { return { text: "data 資料狀態", }; }, props: ["prop"], beforeCreate() { console.log(`beforeCreate! ${this.text}`); console.log(`beforeCreate! ${this.prop}`); }, created() { console.log(`created! ${this.text}`); }, beforeMount() { console.log(`beforeMount! ${this.text}`); }, mounted() { console.log(`mounted! ${this.text}`); }, beforeUpdate() { console.log(`beforeUpdate! ${this.text}`); }, updated() { console.log(`updated! ${this.text}`); }, activated() { alert(`activated! ${this.text}`); }, deactivated() { alert(`deactivated! ${this.text}`); }, beforeUnmount() { console.log(`beforeUnmount! ${this.text}`); }, unmounted() { console.log(`unmounted! ${this.text}`); }, }; const App = { data() { return { isShowing: false, text: "APP data", }; }, }; Vue.createApp(App).component("child", child).mount("#app"); </script> </main> </div> </div> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" /> </body> </html> ``` 查看`<KeepAlive>`範例將註解開啟 ![](https://i.imgur.com/woT1BGl.gif) ```html= <keep-alive> <component v-if="isShowing" is="child" /> </keep-alive> ```