쇼핑몰 프로젝트를 진행하면서, 뒤로가기 시 스크롤 유지 관련한 이슈 해결 히스토리를 기록해보고자 이 글을 작성하게 되었다. 현재 프로젝트에서는 Vue + Vue Router + Vuex 를 사용한다.
개요
현재 진행하던 프로젝트에서는 기존에 sessionStorage에 스크롤 위치를 저장하고, updated 훅에서 모든 화면 update가 끝난 후 sessionStorage에 있는 scroll값을 가져와 scroll을 이동시키는 스크롤을 컨트롤 하고 있었다. 이과정에서 서버 통신 후 데이터를 렌더링하는 시점과, 스크롤을 이동시키는 시점에 오류가 생겨 스크롤을 잘 잡지 못하는경우가 발생하여 로직을 수정하게 되었다.
고려해본 방법들
1. keep-alive 적용
2. web storage 사용
3. router savedPosition 사용
Keep-alive 적용
keep-alive는 컴포넌트를 전환할 때, 성능상의 이유로 상태를 유지하거나, 재 렌더링을 피할 수 있게 해주는 element입니다. 재 렌더링을 피할 수 있기 때문에, 뒤로가기 시 별다른 장치 없이 그대로 화면을 유지할 수 있는 장점이 있다.
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
사용은 이런식으로 원하는 컴포넌트를 <keep-alive> 태그로 감싸주면 된다.
여기서 유의할점은 화면 전체의 재 렌더링을 피하고 싶다면 router-view 전체를 keep-alive 태그로 감싸야 한다는 것이다. (이것때문에 여러번 실패를 했었네요..)
뒤로가기를 누를때만 적용 되야 하기 때문에 동적으로 할당 해야한다. 또한 재렌더링이 안되기 때문에 신중히 사용해야한다.
Web Storage 사용
화면 데이터와 스크롤 위치를 localStorage나 sessionStorage에 담아놓고, 돌아올 때 그대로 다시 불러오는 방법. 새롭게 서버통신을 해서 다시 리스트를 불러오지 않기 때문에 infinity scroll 사용 시 스크롤 위치를 잡기가 용이하다. 또 라이프사이클 훅에서 이루어지는 모든 것들이 정상 동작하므로 keep-alive를 사용할 수 없는 경우(라이프사이클을 거쳐야 하는 경우) 사용하기 좋다.
router savedPosition 사용
vue router는 scroll을 컨트롤 하기 위한 scrollBehavior 라는 함수를 제공하고 있다. 이는 HTML 히스토리 모드에서만 작동하는데, 라우터 객체를 만들때
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// 원하는 위치로 돌아가기
}
})
이 안에 함수를 넣어서 사용하면 된다.
함수 안에서 리턴 값에 따라 스크롤의 위치가 변경되는데, 세번째 전달인자 (여기서는 savedPosition)은 브라우저가 앞/뒤 버튼으로 트리거 될때만 사용 가능하다
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
이런식으로 사용하면 되는데, 무조건 맨 위로 올리고 싶을 때는
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
이렇게 항상 0을 리턴하면 된다.
또 부드럽게 스크롤을 하도록 동작을 컨트롤 할 수도 있는데,
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash,
behavior: 'smooth',
}
}
}
이렇게 behavior에 스크롤 옵션을 입력 하면 된다. (selector는 위에서 설명했던 스크롤 위치이다)
이 이슈를 어떻게 해결하게 되었는지 전체적인 플로우는 다음장에서 설명하겠다.
'프론트엔드 > vue.js' 카테고리의 다른 글
ChunkLoadError 해결기 (1) 문제점 파악 및 테스트 과정 (0) | 2022.03.31 |
---|---|
[SPA] 뒤로 가기 스크롤 유지에 관하여(2) (0) | 2021.12.27 |
웹 최적화 3. 이미지에 lazy loading 적용하기 (0) | 2021.12.13 |
웹 최적화 2. vue.js 라우터 code splitting 적용하기 (0) | 2021.12.06 |
웹 최적화 1. webpack-bundle-analyzer 플러그인을 이용하여 시각화 하기 (0) | 2021.12.01 |