Nuxt3でページ遷移時にページトップにスクロールさせる方法についてです。
ふと、rc.13版にアップグレードしてみるとスクロールトップのオプションが入っているようでした。Transitionのfinishのタイミングでページトップにスクロールされるのがデフォルトの動作のようです。
https://github.com/nuxt/framework/pull/3851
https://github.com/nuxt/framework/pull/3851
環境
-
nuxt@3.0.0-rc.13
- Node.js v16.18.0
サンプルアプリの構成は以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ tree -I 'node_modules' . ├── README.md ├── app │ └── router.options.ts ├── app.vue ├── layouts │ └── default.vue ├── nuxt.config.ts ├── package-lock.json ├── package.json ├── pages │ ├── index.vue │ └── other-page.vue ├── plugins │ └── scrolltop.client.ts └── tsconfig.json 4 directories, 11 files |
本記事作成時、Nuxt3はまだベータリリースのため動作が変わる可能性もあります。
ページ遷移時にスクロールする
page:finish
のフックを使って、scrollTo
関数でページトップにスクロールさせます。
1 2 3 4 5 |
export default defineNuxtPlugin((nuxtApp) => { nuxtApp.hook("page:finish", () => { window.scrollTo({ left: 0, top: 0 }); }); }); |
Transition後にスクロールする
ページコンポーネントのdefinePageMeta
及びapp/router.options
で指定する方法があります。nuxt.config.ts
のrouter.options
ではJSONでserializeされるオプションのみ指定が可能なようです。それぞれ見ていきます。
definePageMeta
definePageMeta
にscrollTop
というプロパティがあります。デフォルトは、true
になっているので、ページ遷移のtransition後にページトップにスクロールされます(page:transition:finish
フックが呼ばれる)。スクロールを無効にする場合は、false
にすればよさそうです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<script lang="ts" setup> definePageMeta({ pageTransition: { name: "fade", mode: "out-in", appear: true, duration: 1000, }, }); </script> <template> <div> <div class="box"> <h1>Index Page</h1> </div> <NuxtLink to="/other-page">別ページ</NuxtLink> </div> </template> <style> .box { height: 1000px; } .fade-enter-active, .fade-leave-active { transition: opacity 0.5s ease; } .fade-enter-from, .fade-leave-to { opacity: 0; } </style> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<script lang="ts" setup> definePageMeta({ pageTransition: { name: "fade", mode: "out-in", appear: true, duration: 1000, }, scrollToTop: false, // スクロールさせない }); </script> <template> <div> <div class="box"> <h1>Other Page</h1> </div> <NuxtLink to="/">ホームページ</NuxtLink> </div> </template> <style> .box { height: 1000px; } .fade-enter-active, .fade-leave-active { transition: opacity 0.5s ease; } .fade-enter-from, .fade-leave-to { opacity: 0; } </style> |
app/router.options.ts
vue-routerのscrollBehavior
を独自に実装します。
1 2 3 4 5 6 7 8 |
import type { RouterConfig } from "@nuxt/schema"; // https://router.vuejs.org/api/interfaces/routeroptions.html export default <RouterConfig>{ scrollBehavior(to, from, savedPosition) { return { left: 0, top: 0 }; }, }; |
参考リンク
- https://v3.nuxtjs.org/guide/directory-structure/pages#page-metadata
- https://github.com/nuxt/framework/pull/3851
- https://router.vuejs.org/guide/advanced/scroll-behavior.html
- https://stackoverflow.com/questions/69902990/page-not-scrolling-to-top-when-route-changes-in-nuxt-js
コメント