목록페이지 ➡️ 상세페이지 ➡️ 목록페이지
목록페이지 재입장시 이전 검색조건이 유지가 되어있어야 한다.
session storage를 활용해 검색조건을 저장해두고,
목록페이지로 다시 돌아왔을 때 저장해둔 검색조건을 다시 꺼내오려고 했다.
다만 상세페이지에 들어갔다 나왔을 때의 조건이 붙으니까
isDetailPage 라는 변수를 하나 만들어서
session storage에 변수 isDetailPage를 검색조건과 같이 저장해두고,
목록페이지에 돌아왔을 때 isDetailPage가 true면 검색조건을 꺼내오는식으로 구현하려고 했다.
문제점이라기 보다 코드가 지저분한 기분이랄까!
목록페이지를 구현하는 컴포넌트내에서만 코드가 작성되면 깔끔할 거 같은데,
상세페이지를 갔다 왔다는 확인이 필요하다보니
상세페이지에서 목록페이지로 넘어올 때 session storage에 있는 isDetailPage를 바꿔줘야하는..
상세페이지를 구현하는 컴포넌트내에서의 코드 수정도 필요했다.
// 컴포넌트 인스턴스가 생성되기 전에 호출된다.
// 인스턴스 생성 전이기 때문에 인스턴스 접근이 불가하며
// 인스턴스 접근을 하고 싶을 경우 next를 통해 인스턴스에 접근하면 된다.
// to: 이동하려는 컴포넌트
// from: 이동하기 전 컴포넌트
// next: 이동할 컴포넌트에 접근하기 위한 콜백함수
beforeRouteEnter(to, from, next) {
next((vm) => {
const searchData = vm.store.getters['searchStore/searchData'];
// 목록페이지로 오기전 페이지가 상세페이지고, searchData가 있다면
// setup()함수안에 있는 변수 srch에 값을 하나씩 넣어주는 로직
if (
['contractDataDtl', 'newContractData', 'contractDataModi'].includes(
from.name
) &&
searchData
) {
Object.keys(searchData).forEach((d) => {
vm.srch[d] = searchData[d] || null;
});
} else {
// 목록페이지로 오기 전페이지가 상세페이지가 아니라면 store에 있는 값 null로 초기화
vm.store.commit('searchStore/setSearchData', null);
}
코드생략
});
},
beforeRouteLeave(to) {
// 상세 or 등록 페이지 이동시 검색 조건 저장
if (['contractDataDtl', 'newContractData'].includes(to.name)) {
this.setSearchData();
}
},
beforeRouteEnter()와 beforeRouteLeave()를 사용해서
목록페이지 컴포넌트에서 검색조건유지 로직을 완성할 수 있다.
다만 사용하려는 vue-router 함수는 Options API에서 사용가능하기 때문에
Vue3의 composition API에서는 사용할 수 없고, Options API로 코드 작성해줘야한다.
<script>
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore()
return { store }
}
beforeRouteEnter(to, from, next) {
// 코드생략
},
beforeRouteLeave(to) {
// 코드생략
},
}
</script>
vue3에서 사용하는경우 위와같이 작성해줘야하고,
beforeRouteEnter()나 beforeRouteLeave()에서 setup안의 변수나 메소드를 사용하고 싶다면
꼭 return을 해줘야한다.
( script setup 에서 사용하는거면 따로 return은 안해줘도 될 듯! )
✔️ setup(composition API) > Init Options API > onMounted 순으로 생명주기가 된다는 점!
위에 작성한 코드 중 아래와 같은 코드가 있다.
검색조건유지를 적용해야할 페이지가 여러개 있었다.
A라는 목록페이지에서 검색조건유지하고 있다가
B라는 목록페이지로 갔을 떄 store에 있는 state값을 조회하면 null이 나와야하는데 값이 있는채로 출력이 되더라!
else {
// 목록페이지로 오기 전페이지가 상세페이지가 아니라면 store에 있는 값 null로 초기화
vm.store.commit('searchStore/setSearchData', null);
}
위의 코드로 목록페이지 오기 전의 페이지가 상세페이지가 아니라면
store에 있는 state값을 null로 초기화 하는데
왜 값이 있는채로 출력되는지 추척을 해봤다.
<script>
export default {
setup() {
const store = useStore()
**const test = store.state.searchStore.srch**
onMounted(() => {
console.log(test) // 요렇게 하면 값이 있는채로 나 오고
console.log(store.state.searchStore.srch)// 요렇게하면 null이 나온다.
})
return { store }
}
</script>
위에 주석에 써놓은 글처럼
미리 setup()에서 store의 state 변수를 가져와 변수에 담아두면 값이 있는채로 나오고,
onMounted()에서 store에 있는 state를 직접 가지고 오면 null이 나온다.
생명주기랑 관련이 있는건데,
setup()가 제일 먼저 생성되고 ( = 이때 test변수에 이미 값이 있는채로 들어감 )
그 다음 Init Options API()가 실행되면서 beforeRouteEnter()가 실행이 된다.
beforeRouteEnter()때
vm.store.commit('searchStore/setSearchData', null) < 이 코드로
store에 있는 state 변수를 null로 초기화 하는거라
test는 값이 있게 출력되고
store.state.searchStore.srch는 null로 나오는 것!
생명주기 잘 알고있다고 생각했는데
막상 options API가 섞인 코드로 기능 구현하다보니 생명주기에 대해 놓치고 있던 부분이 있다는걸 알게 되었다.
이렇게 정리하면서 기록으로 남겨둘 수도 있고 기억에도 남아있을거 같아서 좋은 경험이였다고 생각한다!
➕ Level up (+1)
오늘도 하나 배워따 만족!