ページ内の移動には、vue-scrolltoを使ってたけど、
vue-routerだけでもいけそうだったのでためしてみた(*´ω`*)
ちなみに、Nuxt2での設定。
簡単な使い方
nuxt.config.ts
のrouter.scrollBehavior
に設定を加えると、
いろいろ振る舞いを変えれるらしい(*´ω`*)
// nuxt.config.ts import { NuxtConfig } from "@nuxt/types"; const config: NuxtConfig = { router: { scrollBehavior(to, from, savedPosition) { if (to.hash) { return { selector: to.hash, behavior: 'smooth' } } } } }; export default config;
注意点
上の例だけでよさそうだと思ったけど、
実際使ってみると、いろいろ調整が必要だった。。
- ページ遷移アニメーションをつけている場合、
setTimeout
などを使ってすこし待つ必要がある - idが日本語などの場合、hashがエンコードされているため、デコードする必要がある
- ヘッダなどをfixedなどにしている場合、オフセットを設定する必要がある
最終的な設定
最終的にはこんな感じ(*´ω`*)
型定義が無いのもあるので、いくつか手動で用意。。
// nuxt.config.ts import { NuxtConfig } from "@nuxt/types"; const config: NuxtConfig = { /* * Router configuration */ router: { scrollBehavior(to, from, savedPosition) { type Pos = { x: number; y: number }; type Pos2 = { selector: string; offset?: Pos; behavior?: ScrollBehavior }; type PosResult = Pos | Pos2 | void; const getPos = (to: Route, from: Route, pos: Pos | void): PosResult => { // idが日本語の場合は、デコードが必要 const hash = decodeURIComponent(to.hash); // ヘッダをfixedやstickyにしている場合は、オフセットをつける const offset: Pos = { x: 0, y: 48 }; // 遷移先がハッシュの場合 if (hash) return { selector: hash, behavior: "smooth", offset: offset }; // 遷移先にハッシュがなく、同一ページの場合 else if (to.name == from.name && from.hash) { return { selector: "body", behavior: "smooth", offset: offset }; } // 保存したPositionがある場合 else if (pos) return pos; // デフォルト else return { x: 0, y: 0, offset: offset }; }; // 同一ページの場合は、すぐにスクロールする if (to.name == from.name) return getPos(to, from, savedPosition); // 異なるページの場合は、遷移アニメーションがあるので、少し待ってからスクロールする else { return new Promise((resolve, _) => setTimeout(() => resolve(getPos(to, from, savedPosition)), 400) ); } } }, }; export default config;
以上!! 便利(*´ω`*)
細かい設定はできないけど、シンプルなのであれば、これでいいかも(*´ω`*)