iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
JavaScript

歡迎參加我的原生JS畢業典禮系列 第 12

【Day11】Vue生命週期—Lifecycle Hooks ft.Composition API

  • 分享至 

  • xImage
  •  

一開始只看到中譯想說到底為什麼要叫「生命週期鉤子」,看到Hooks…好吧。在之前的ToDoList練習還尚未學習Vue生命週期的概念,所有狀態和動作在頁面都亂亂放也沒有報錯(當然是錯誤示範);前幾章我們碰到了Components,了解全域組件的註冊位置:在根實體創建之後且被綁定渲染之前。除了要把對的任務放在對的位置,後續的註銷作業也很重要!
Vue的生命週期

實體的建立

使用Vue3的Composition API(以紅字標示),語法跟上圖有些差異,以下對應說明:

  • beforeCreate()/setup():實體剛初始化完成即被調用,但其他狀態和事件都還沒初始化。
  • created()/setup():相關狀態如propdata…與事件建立完成,但$el(元素)尚未配置。
  • beforeMount()/onBeforeMonut():實體與$el配置前調用,此時$el仍是尚未渲染的初始模板。
  • mounted()/onMounted():實體與$el完成安裝配置,此時頁面已渲染為可視頁面。

◎小提示:用Composition API寫到這裡都不陌生<script setup>標籤,所以setup()是用於非建構式組件之中!

onBeforeMount()

我們建立一個$el叫做newDiv,和一個字串資料str,在onBeforeMount()階段print出來看看:

import { ref, onBeforeMount } from 'vue'
const newDiv = ref()
const str = HelloWorld
onBeforeMount(() => {
    console.log('Hook:OnBeforeMount')
    console.log(str);
    console.log(newDiv.value);
})

<div class="about">
    <div ref="newDiv"></div>
</div>

https://ithelp.ithome.com.tw/upload/images/20240926/20169356yXgFlrcRRL.png
◎說明:在這個階段組件已經完成狀態和事件的初始化,所以str已經可以被讀取;而newDiv$el)因為還沒被掛載,所以仍是undefined狀態。

onMounted()

加碼讓onMounted()也加入,看看有什麼變化:

import { ref, onBeforeMount,onMounted } from 'vue'
const newDiv = ref()
const str = HelloWorld
onBeforeMount(() => {
    console.log('Hook:OnBeforeMount')
    console.log(str);
    console.log(newDiv.value);
})
onMounted(() => {
     console.log('Hook:onMounted')
     console.log(str);
     console.log(newDiv.value);
})

<div class="about">
    <div ref="newDiv"></div>
</div>

https://ithelp.ithome.com.tw/upload/images/20240926/20169356Crp1nsdHUn.png
不出所料,newDiv完成了初次渲染可以print出<div></div>了!

實體的更新

  • beforeUpdate()/onBeforeUpdate():響應式狀態已改變,但在更新畫面之前的Hook。
  • updated()/onUpdated():響應式狀態改變且更新完畫面。

onBeforeUpdate()、onUpdated()

我們把str改為響應式資料放入newDiv容器中,改變str的值看看變化:

import { ref,onUpdated,onBeforeUpdate } from 'vue'
const newDiv = ref()
const str = ref("HelloWorld")
onBeforeUpdate(() => {
    console.log('Hook:onBeforeUpdate')
    console.log(str.value);
    console.log(newDiv.value);
})
onUpdated(() => {
    console.log('Hook:onUpdated')
    console.log(str.value);
    console.log(newDiv.value);
})
function changeText() {
    str.value = "WorldChange"
}

<button @click="changeText">點我改變資料</button>
<div ref="newDiv">{{str}}</div>

接著是…放送事故時間!(每天一卡關)
https://ithelp.ithome.com.tw/upload/images/20240926/20169356JJwqQiAX5Q.png
預期div會顯示原本的HelloWorld結果竟然已經被更新ChangeWorld了!
※在<script setup><script>都試過,也換過reactive試試看,仍然抓不到onBeforeUpdate前$el的狀態…又要先暫時留下一個未解之謎了

實體的銷毀

  • beforeUnmount()/onBeforeUnmount():在組件與實體被卸載銷毀之前調用。
    ◎所有響應式資源已停止,在這個階段可以進行進行計時器、DOM監聽器的卸載、子元件卸除,釋放資源也避免副作用產生。
  • unmounted()/onUnmounted():實體被銷毀完畢。

小結

雖然在Update環節又沒有出現預期的狀態,不過執行onUpdated()期間若有data又被異動的情況下,很有可能會進入無限循環,對此,使用computed屬性相對合適。更多相關Hooks應用,詳見:Vue-組合式API生命週期


參考資料
Vue-生命週期選項
Vue-組合式Api生命週期選項
勇者鬥Vue龍-Vue實體的生命週期
重新認識Vue.js-1-7 元件的生命週期與更新機制


上一篇
【Day10】組件間溝通—Vue Prop&Emit
系列文
歡迎參加我的原生JS畢業典禮12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言