背景
Vue3での開発中、画面遷移後に表示位置が画面最上部にならなかった。
原因として、SPA(Single Page Application)であるため、画面遷移時に前画面の画面表示位置が引き継がれてしまっていた。
画面遷移後に画面最上部までスクロールさせようとしたが、すんなりと実装できなかったため備忘録として残します。
試したこと
mounted
mountedにscrollTo()を入れ、DOM読み込み後にスクロールさせる。
意図した動作はしなかった。ざっと調べたが、DOMの更新が非同期処理なのが原因らしい。
mounted
mounted() {
window.scrollTo({top: 0, left: 0, behavior: "instant"});
}
nextTick
DOMの更新完了後に処理を実行したい場合に使うものらしい。が、意図した動作はせず、、、
nextTick
mounted() {
this.$nextTick(() => {
window.scrollTo({top: 0, left: 0, behavior: "instant"});
});
}
setTimeout
単純に少し待ってみる。想定に近い動作はするが、読み込みが遅いケース等を考慮すると適切な待ち時間がどの程度なのかわからない。何より力技すぎてイカしてないので最終手段とすることに。
setTimeout
mounted() {
setTimeout(() => {
window.scrollTo({top: 0, left: 0, behavior: "instant"});
},10);
}
結論
afterEach
ページの遷移後に実行したい場合に使うものらしい。想定通りの動きをしているし公式ドキュメントを読んだ限りこれがベストっぽい。
afterEach
mounted() {
$router.afterEach(() => {
window.scrollTo({top: 0, left: 0, behavior: "instant"});
});
}
おわりに
SPAのページ遷移については気をつけないといけないと改めて感じた。また、Vueのライフサイクルについての知識が乏しいので気が向いたら勉強しないと、、、
setTimeoutに妥協せず最適解に辿り着けたのは満足。