‼️

半年間の長期インターンを始めたので、1ヶ月ごとに学んだこととかを吐き出してみるの会【10月編】

2024/11/11に公開

これまでの記事

これまでの記事は、下記からご覧ください。
https://zenn.dev/lnest_knowledge/articles/9e27e740f7fd54
https://zenn.dev/lnest_knowledge/articles/ed5f9306d774c0
https://zenn.dev/lnest_knowledge/articles/8b62bdd442bc73

はじめに

今月のテーマは、

  1. Vue3におけるライフサイクルについて
  2. Vue3 / Nuxt3で可変式サイドバーを実装した件
    の2つになります。

コードを書くなかで、onMounted()内に色々書いていましたが、具体的なタイミングや用途、他のフックなどがなんとなくで使っていた状態なので、これを機にまとめておこうと思います。

Vue3におけるライフサイクル

公式Docs
公式Docsがかなり丁寧にまとまっているので、Docsを読み込むとオススメ。

Vue3のコンポーネントは、生成から破棄までの間に一連のライフサイクルと呼ばれる段階を踏んでいきます。

  1. beforeCreate / created:Vueのインスタンスの初期化・生成
  2. beforeMount / mounted:コンポーネントのマウント
  3. beforeUpdate / updated:リアクティブなデータの変更
  4. beforeUnmount / unmounted:マウントしたコンポーネントのアンマウント

見てわかると思いますが、各段階で処理開始前(接頭語としてbeforeが用いられている)と後(過去形を用いている)の2つがあります。上記に上げたのは、生成から破棄までの基本的な流れになります。

その他にも
errorCaptured:エラーをキャッチしたときに呼び出される
renderTracked:コンポーネントがレンダリングされる際に、そのコンポーネントが依存しているリアクティブなデータを追跡し、データの変更がされたとき、どのコンポーネントを再レンダリングするべきか特定できる
など、まだあと3つくらいありますが、こういったライフサイクルがあります。

Vue3のライフサイクルフック

ここからは、実際にライフサイクルを通る際に呼び出される「ライフサイクルフック」を紹介します。

onMounted()

onMounted()はコンポーネントがDOMにマウントされた後に実行されるライフサイクルフック。
このフックは、コンポーネントのレンダリングが完了し、実際のDOM要素が作成された後に呼び出される。
APIやデータベースなどの外部からデータを取得するときやDOMを操作したいとき、子コンポーネントの参照など、主に初期化処理などに最適。

<template>
    <div>
        <h1>{{ title }}</h1>
        <p>{{ message }}</p>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const title = ref('Welcome')
const message = ref('Loading...')

onMounted(async() => {
    console.log('Component is mounted!')
    document.title = title.value
    message.value = 'Hello from onMounted!'
})
</script>

onUpdated()

onUpdated()はコンポーネントが更新された後に実行されるライフサイクルフック。このフックは、データの変更によって、DOMが更新された後に処理をしたいときに使うことが多い(イメージ)。具体的な例としては、動的コンテンツの更新後にスクロール位置を調整したり、状態の変更を外部ライブラリに反映させる場合などが挙げられる。

<template>
    <div>
        <h1>{{ count }}</h1>
        <button @click="increment">Increment</button>
    </div>
</template>

<script setup>
import { ref, onUpdated } from 'vue'

const count = ref(0)

function increment() {
    count.value++
}

onUpdated(() => {
    console.log('Component updated!')
    console.log('New count:', count.value)
})
</script>

onUnmounted()

onUnmounted()はコンポーネントがアンマウントされた後に実行されるライフサイクルフック。
このフックは、コンポーネントが破棄される際に、クリーンアップ(イベントリスナーの削除やWebSocket接続のClose処理など)に最適。

<template>
    <div>
        <h1>{{ title }}</h1>
    </div>
</template>

<script setup>
import { ref, onUnmounted } from 'vue'

const title = ref('Goodbye')

onUnmounted(() => {
    console.log('Component is unmounted!')
    // クリーンアップ処理をここに記述
})
</script>

onBeforeMount()

onBeforeMount()はコンポーネントがマウントされる直前に実行されるライフサイクルフック。

<template>
    <div>
        <h1>{{ message }}</h1>
    </div>
</template>

<script setup>
import { ref, onBeforeMount } from 'vue'

const message = ref('Initial message')

onBeforeMount(() => {
    console.log('Component is about to be mounted!')
    message.value = 'Updated before mount'
})
</script>

onBeforeUpdate()

onBeforeUpdate()はコンポーネントが更新される直前に実行されるライフサイクルフック。
更新される前のデータを取得して、なにか処理したい場合に便利。

<template>
    <div>
        <h1>{{ count }}</h1>
        <button @click="increment">Increment</button>
    </div>
</template>

<script setup>
import { ref, onBeforeUpdate } from 'vue'

const count = ref(0)

function increment() {
    count.value++
}

onBeforeUpdate(() => {
    console.log('Component is about to update!')
    console.log('Current count:', count.value)
})
</script>

onBeforeUnmount()

onBeforeUnmount()はコンポーネントがアンマウントされる直前に実行されるライフサイクルフック。

<template>
    <div>
        <h1>{{ title }}</h1>
    </div>
</template>

<script setup>
import { ref, onBeforeUnmount } from 'vue'

const title = ref('Farewell')

onBeforeUnmount(() => {
    console.log('Component is about to be unmounted!')
    // 最終的なクリーンアップや状態の保存をここで行う
})
</script>

Vue3 / Nuxt3で可変式サイドバーを実装した件

別記事にまとめましたので、そちらをご覧ください。
https://zenn.dev/lnest_knowledge/articles/9af098d0788070

終わりに(余談)

最近、個人で使っているM1 MacBook Pro君がモニターに繋げると、若干熱を持つことが多くなったり、動画を見ながらコーディングをしていると、割と熱くなってくるようになったので、Magic Keyboardを購入しました。かなり快適になったので、来月また、Magic Trackpadを導入しようかなと、夜も眠れないくらい葛藤しています()。そんなこんなで、今年も残り2ヶ月、突っ走っていこうと思います。

リバナレテックブログ

Discussion