0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nextTickを使ったレイアウト調整のコツ

Last updated at Posted at 2025-03-31

はじめに

こんにちは、Gakken LEAP のエンジニアの Minami です。
Vue.js で開発をしていると、「データを更新したのに、DOM に反映されるのが遅い…」と感じたことはありませんか?
特に、要素の高さを取得したり、スクロール位置を調整したりするときに、この問題が発生しやすいです。

そんなときに便利なのが、Vue の nextTick です!
nextTick を使えば、Vue の非同期レンダリングのタイミングを理解しつつ、意図したタイミングで DOM 操作を行うことができます。

本記事では、nextTick の基本的な使い方から、実際のレイアウト調整で役立つテクニックまでを詳しく解説していきます。

nextTick とは?

nextTick は、Vue のリアクティブな変更が DOM に適用された後に実行されるコールバックを登録するためのユーティリティです。

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

const showElement = ref(false);

const toggleElement = async () => {
  showElement.value = !showElement.value;
  await nextTick();
  console.log('DOM 更新後の状態:', showElement.value);
};
</script>

<template>
  <button @click="toggleElement">トグル</button>
  <div v-if="showElement">表示されました!</div>
</template>

nextTick を使うことで、showElement の変更が DOM に反映された後に処理を実行できます。

レイアウト調整で nextTick を活用する方法

1. 要素の高さを取得する

コンテンツを開閉するアニメーションを実装する際、要素の高さを取得する必要があります。しかし、リアクティブなデータが更新されても、DOM の変更がまだ反映されていない場合があります。

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

const show = ref(false);
const contentHeight = ref('0px');
const contentRef = ref(null);

const toggleContent = async () => {
  show.value = !show.value;
  await nextTick();
  contentHeight.value = show.value ? `${contentRef.value.scrollHeight}px` : '0px';
};
</script>

<template>
  <button @click="toggleContent">トグル</button>
  <div ref="contentRef" :style="{ height: contentHeight, overflow: 'hidden', transition: 'height 0.3s' }">
    <p>このコンテンツが開閉されます</p>
  </div>
</template>

nextTick を使わないと contentRef.value.scrollHeight を取得する前に div が表示されておらず、正しい高さが得られない可能性があります。

2. レンダリング後にスクロール位置を調整する

リストの追加やタブの切り替え時に、スクロール位置を適切に設定するのにも nextTick が役立ちます。

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

const items = ref(['アイテム 1', 'アイテム 2']);
const listRef = ref(null);

const addItem = async () => {
  items.value.push(`アイテム ${items.value.length + 1}`);
  await nextTick();
  listRef.value.scrollTop = listRef.value.scrollHeight;
};
</script>

<template>
  <button @click="addItem">アイテムを追加</button>
  <div ref="listRef" style="height: 100px; overflow-y: auto; border: 1px solid #ddd;">
    <div v-for="item in items" :key="item">{{ item }}</div>
  </div>
</template>

これにより、新しいアイテムが追加された後にリストの一番下までスクロールするようになります。

nextTick のメリットとデメリット

メリット

  1. 正確なDOM操作が可能
    • Vue の非同期レンダリングによって生じるタイミングのズレを解消し、正しく要素のサイズやスクロール位置を取得できる。
  2. アニメーションの精度向上
    • nextTick を使用することで、CSS トランジションやアニメーションの開始タイミングを正しく制御できる。
  3. 非同期処理との相性が良い
    • await nextTick() を使うことで、API 呼び出し後の DOM 更新などを適切に管理できる。

デメリット

  1. 不要な使用でパフォーマンスが低下する可能性
    • nextTick を過剰に使用すると、余計な再描画が発生し、アプリケーションのレスポンスが低下する可能性がある。
  2. 同期処理のつもりが非同期になることがある
    • nextTick を使うと、コードの実行タイミングが非同期的になり、予期せぬ動作を招く場合がある。
  3. Vue の更新フローを理解していないと誤用しやすい
    • Vue のリアクティブシステムを正しく理解していないと、nextTick を適切に使えず、不要なバグを引き起こす可能性がある。

まとめ

Vue.js の nextTick は、DOM 更新後に処理を実行するための便利なツールです。特にレイアウト調整が必要な場面では、

  • 要素のサイズを取得する
  • スクロール位置を調整する
  • アニメーションの制御を行う

といった用途で活用できます。ただし、無駄に使いすぎるとパフォーマンスが低下するため、適切なタイミングで利用することが重要です。

この記事を参考に、Vue のレンダリングを理解しながら効果的に nextTick を活用してください!


エンジニア募集中

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?