🚴‍♀️

NuxtLinkのアニメーション実装時に、DOMExceptionが出た場合

2023/06/11に公開

一体何が起こったんだい?

Nuxt3で画面遷移時にアニメーションを設定した際、
アニメーションが終了する前に再び画面遷移しようとするとDOMExceptionが発生しました。
一度エラーが発生するとリロードしなければ詰んでしまうので、早急に対処せねばとなりました。

アンカーテキスト

エラーメッセージは以下のようになっています。

結論

コミュニティ内で議論はされているものの、最善策は未だに見つかっていない模様
(というか、フレームワークのコアな部分なのでこちらからアプローチする方法がない?)

https://github.com/nuxt/nuxt/issues/13350

そういうわけで代替案ではあるものの、下記の実装がいいのかなとなりました。

  • ユーザーがアニメーションを終了するまでルーティングできないようにする。
  • エラーが発生した場合、リロードするイベントを作成する。
  • 画面遷移時のアニメーションの実装は避ける。

実装(修正なし)

これといって特別なことはありませんが、下記のような実装となっています。

layout.vue
<template>
  <div>
    <NuxtLink :to="/">
      Home
    </NuxtLink>
		
    <NuxtLink :to="/about">
      About
    </NuxtLink>
 </div>
</template>
nuxt.config.ts
  app: {
    pageTransition: { name: "layout", mode: "out-in" },
  }
app.vue
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

<style>
.layout-enter-active,
.layout-leave-active {
  transition: all 0.8s;
}
.layout-enter-from,
.layout-leave-to {
  transform: translateX(800px);
  opacity: 0;
}
</style>

実装(ルーティング防止修正)

指針

指針を元に改良

layout.vue
<script setup>

// アニメーション中か判定するフラグ
const isAnimation = ref(false);

// NuxtLinkをクリックした時の処理
const animationProcess = (linkPath) => {

  // 既に表示している画面に対してのクリック -> 処理終了
  if(linkPath === useRoute().fullPath) {
    return;
  }

  // アニメーションフラグをtrueに
  isAnimation.value = true;

  // 2000ms後にfalseにするイベントを追加
  window.setTimeout(() => {
    isAnimaiton.value = (false);
  }, 2000);

</script>

<template>
  <div
  class = {"event-none":isAnimation.value}
  >
    <NuxtLink 
    :to="/"
    @click="animationProcess('/')"
    >
      Home
    </NuxtLink>
		
    <NuxtLink 
    :to="/about"
    @click="animationProcess('/about')"
    >
      About
    </NuxtLink>
 </div>
</template>

<style>
.event-none {
pointer-events : none;
}
</style>

修正結果


クリックしようとしてもCSSでイベントを無くしているため、できないことがわかります。

手順

  1. NuxtLinkがクリックされた時にイベントが発生し、アニメーションフラグを立てる。
  2. NuxtLinkの親要素のdiv要素にクラスをバインドし、CSS「pointer-events:none」を動的に追加する。
  3. window.setTimeoutでイベントを作成し、n秒後に発火。
  4. 3で作成したイベントが発火することで、アニメーションフラグが落ちる。

注意点

まとめ

現状はごまかし程度でしか実装ができなかったので、
これからのアップデートで改善されることを期待しています。
(Vue開発者、コミュニティのみなさんには頭が上がらないです😇)

ここからは自身の話となりますが、
1年前にVueと出会いとても楽しいプログラミング生活をおくっています。
そのため技術力はよわよわですが、発信することで成長に繋げたいと思い今回執筆しました。
(間違ったことやもっといい方法があれば教えてください笑)

現在はSESとして業務システム関連を作っていますが、
いつかWebの世界で働けるように精進していきたいと思います!

拙い記事ですが、見てくださりありがとうございました!

Discussion