Vue3 DOMの変更を検知して処理を行いたい時についてまとめる
onMounted()
コンポーネントがマウントされた後に呼び出されるコールバックを登録します。
Vue3を利用したプロジェクトでは(Nuxtでも同様に) onMouted()
で処理をすることが多々あると思います。そこでは文字通りコンポーネントがマウントされた時に行いたい処理を記述します。
例えば、APIからデータをフェッチしておいて、コンポーネントで描画する。
<script setup>
import { ref, onMounted } from 'vue'
const fetchedData = ref()
onMounted(() => {
axios.get(`http://nanikasirano-api`).then((res) => {
console.log('res', res)
fetchedData.value = res.data
}).catch(err => {
console.log('err', err)
})
})
</script>
<template>
<div>{{ fetchedData }}</div>
</template>
onUpdated()
コンポーネントがリアクティブな状態変更によって DOM ツリーを更新した後に呼び出されるコールバックを登録します。
onUpdated
の場合は、マウント時ではなくDOMツリーが更新した後に処理が行われるので
DOMに何らかの更新があった際に行いたい処理を記述します。
例えば、クリックイベントでcount
変数に変更があった時、別の変数updatedCount
もそれに応じて処理を加える
<script setup>
import { ref, onUpdated } from 'vue'
const count = ref(0)
const updatedCount = ref(0)
onUpdated(() => {
// テキストの内容は、現在の `count.value` と同じでしょう
console.log(document.getElementById('count').textContent)
updatedCount.value = document.getElementById('count').textContent
updatedCount.value++
})
</script>
<template>
<button id="count" @click="count++">{{ count }}</button>
</template>
この場合はupdatedCount
にDOMから取得したcount
の値を入れ、+1する処理をしているので
updatedCount
は常にcount
の+1した値になる
onUpdatedの注意点として、無限ループを引き起こす可能性があるため、データ変更時に無限ループに陥らないように注意することが重要です。
他にも値の変更を検知して、変更に応じた処理をしたいときはウォッチャー (Watcher) を利用することもできます
ウォッチャー(watch)
watch 関数 を使用することでリアクティブな状態の一部が変更されるたびにコールバックを実行することができます
watch(
() => obj.count,
(count) => {
console.log(`count is: ${count}`)
}
)
nextTick()
特定の状態変更の後に更新された DOM へアクセスする必要がある場合は、代わりに nextTick() を使用してください。
<script setup>
import { ref, nextTick } from 'vue'
const count = ref(0)
function onClick() {
// DOM はまだ更新されていない
const fetchedData = fetchSomeData()
nextTick()
// ここでは DOM が更新されている
scrollToTargetPlace('#scrollToHere')
}
</script>
<template>
<button @click="onClick">ボタン</button>
<div v-if="fetchedData">
<div id="scrollToHere"></div>
</div>
</template>
このコードではonClickイベント時にスクロールさせたいけど、DOMの描画を待ってからでないとDOMが生成されてないのでスクロールできない場合に利用しています。スクロールの場合、処理のタイミングによってはうまく動作しないことがあるのでこの関数でうまくタイミングを調整することで適切なタイミングでイベントを発生させることができます。
いずれの関数もDOMの状態を細かく検知して処理を行うことができるので非常に便利です。
参考文献
Discussion