
vue-router를 사용하던 도중 문제가 발생했다.
A 페이지에서 B 페이지로 이동하는데, A페이지에서 스크롤했던 만큼 B 페이지에서 스크롤되어 있는 채로 화면이 전환된다는 이슈가 발생했다.
페이지가 이동할때마다 당연히 최상단으로 페이지가 고정이 되어야 하는데 말이다.
우선 어지간한 구글링은 해봤다.
다들 꼽은 방법이 vue-router의 scrollBehavior 를 이용해 left와 top을 고정하라는 조언들이 90% 이상이었다. 나는 그래서 아래와 같이 index.js에 전역 router를 설정해두었다.
const router = createRouter({
history: createWebHistory(),
scrollBehavior: (to, from, savedPosition) => {
return { left: 0, top: 0 }
},
routes
})
결과는?
실패
디버깅 결과 top: 0으로 제대로 동작중이었지만, 스크롤이 나아지질 않았다.
(뒤에 보면 알겠지만, 대부분의 경우 여기서 해결되는게 정상이다. 혹시 문제때문에 들어왔다면, 이거까진 해보고 가보길 추천한다.)
자, 하나하나 꼼꼼히 문제점을 찾아보기 시작했다.
우선 구글링을 통해 나온 일반적인 Vue와는 다르게 나는 Quasar Framework를 사용중이었다. 그래서 아래와 같이 MainLayout을 잡아둔 상태였다.
<q-page-container>
<q-page class="fit scroll-y">
<router-view v-if="layoutStore.lnbInfo.length > 0" :key="$route.fullPath" />
</q-page>
</q-page-container>
혹시, 따져보면 화면은 스크롤 된적이 없고(전체 HTML) 저 내부 q-page내의 router-view만 스크롤 되었기 떄문에 백날천날 top: 0을 반환해도 의미가 없던 것 아닐까.
document.querySelectorAll('*').forEach(el => {
if (el.scrollHeight > el.clientHeight) console.log(el);
});

우선 위의 코드를 브라우저의 콘솔에 입력해, 페이지에 어떤 element들이 스크롤할 수 있는 element인지 식별해준다.
const router = createRouter({
history: createWebHistory(),
scrollBehavior: (to, from, savedPosition) => {
document.querySelector('.scroll')?.scrollTo(0, 0)
return { left: 0, top: 0 }
},
routes
})
그 다음, 저 요소들중에 내가 필요한 부분이었던 .scoll클래스가 스크롤 이슈가 있었다는 것을 발견했고, 위와 같이 직접 scrollTo()를 사용해 router를 통한 페이지 이동이 있을때마다 직접 스크롤을 위로 끌어올렸다.
이렇게 해결했다.
혹시나 Quasar를 사용하거나, 아니면 Layout을 나와 같이 잡아놓은 분들이 있다면 도움이 되길 바란다.
(난 초보라 삽질 몇시간 했는지 모른다…)