Open3

nuxt 3.17 で変わる useAsyncData の挙動についての調査

wattanxwattanx

まずは同じ key の useAsyncData をもつページを二つつくる

index.vue
<script setup lang="ts">
const todo = ref<{ todo: string; id: number } | null>(null);

const { status } = useLazyAsyncData("index", async () => {
  console.log("call handler");
  const res = await $fetch<{ todo: string; id: number }>(
    "https://dummyjson.com/todos/random"
  );

  todo.value = res;
});
</script>
same-key.vue
<script setup lang="ts">
const todo = ref<{ todo: string; id: number } | null>(null);

const { status } = useLazyAsyncData("index", async () => {
  console.log("call handler 2"); // ここが index.vue との差分
  const res = await $fetch<{ todo: string; id: number }>(
    "https://dummyjson.com/todos/random"
  );

  todo.value = res;
});
</script>
wattanxwattanx

二つのページ遷移での callback の実行に関する違い

useAsyncData に設定した callback がどう実行されるかに違いがある
ページ遷移は NuxtLink を使う。

Nuxt 3.16 の場合

/ へ遷移したあと /same-key に遷移すると以下のようにログが表示される

 console.log("call handler");
 console.log("call handler 2");

Nuxt 3.17 の場合

/ へ遷移したあと /same-key に遷移すると以下のようにログが表示される

 console.log("call handler");
 console.log("call handler");

つまり、同じ key の場合は最初に設定した callback が実行される。
このとき warning が表示される

[nuxt] [useLazyAsyncData] Incompatible options detected for "index" (used at http://localhost:3000/_nuxt/pages/same-key.vue?t=1747664830158:12:24):
- different handler
You can use a different key or move the call to a composable to ensure the options are shared across calls.

最初に設定した callback が実行されるので、same-key.vueuseAsyncData の外側にある todo は更新されない
また key が被ってる場合、ブラウザバックしたときも callback がうまく動かないので、callback で外側の ref を更新したりする場合は key がかぶることを避けたほうが良さそう

demo: https://stackblitz.com/edit/github-1bxtmpqb-alwyug2t