はじめに
Vue.jsを使用して実装している最中に、こんな状況に陥ったことはありませんか?
「ページ遷移した際に、前ページのスクロール位置が引き継がれてしまい、新しいページが最上部から表示されない」
私自身はVue.jsを学習し始めて3ヶ月程度の時にこの課題に直面し、JavaScriptのscrollTop()
やscrollIntoView()
などを使って試行錯誤を繰り返していましたが、なかなか上手くいかなかった記憶があります...
結論
この課題に対してはVue Router
のscrollBehavior()
を使用して解決可能です。
そもそも何故前ページのスクロール位置が引き継がれるの?
この挙動は、ブラウザのデフォルトの挙動によるものです。Vue.jsやその他のSPA(シングルページアプリケーション)では、JavaScriptを使用して動的にコンテンツを読み込むため、挙動が異なります。
ブラウザとSPAにおける挙動の違い
ブラウザは通常、ユーザーがページを離れたときのスクロール位置を記憶し、同じページに戻った時にその位置に自動で戻る機能を持っています。これは、同一ページ内でリンクをたどったり、ページを再訪したりする場合に便利です。この機能は、HTMLの仕様である History API
の一部として実装されています。しかし、SPAではページ間の遷移が実質的には同一ページ内でのビューの切り替えとなるため、ブラウザは自動的にスクロール位置をリセットしません。これは、ページ遷移が物理的に新しいページへの移動として認識されないためです。
解決方法
Vue-Router
のScrollBehavior()
関数を活用してこの課題を解決しましょう。
既存のcreateRouter()
内の処理にscrollBehavior()
の処理を追加します。
以下はページ遷移時に必ずページの最上部から表示させるための例です。
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
return { top: 0 }
},
})
scrollBehavior()
内の引数はそれぞれ以下を指しています。
- to: 遷移先のルートオブジェクト
- from: 遷移元のルートオブジェクト
- savedPosition: ブラウザの進む・戻る操作によるページ遷移で、以前のスクロール位置が保存されている場合にこの位置情報を含むオブジェクト
おわりに
Vue Router
のscrollBehavior()
を適切に利用することで、SPAにおけるスクロール位置を制御し、ナビゲーションのユーザーエクスペリエンスを大きく向上させることができます。今回紹介した基本的な例から始めて、要件に応じてカスタマイズを進めてみてください。