사용자는 뒤로 가기 버튼을 통해 이전 화면으로 이동하길 기대합니다.
라우터를 사용한 일반적인 경우라면 화면 전환에서 굳이 뒤로 가기 버튼 같은 걸 신경 쓸 필요가 없이
브라우저 뒤로가기 누르면 이전 페이지로 이동함니다...
하지만 라우터와 url없이 페이지가 이동하는 컴포넌트라...게다가 모바일 웹을 위한 컴포넌트 였기에...
컴포넌트 내 '닫기' 버튼 같이 버튼으로 관리하면 될 듯 싶었으나... 막상 핸드폰으로 열어봤더니 드럽게 불편하다......
지피티가 vuex니 뭐니 무슨무슨 방법이 있다고 했는데 최대한 뭐 덜 붙이고 popstate를 활용해
<template>
<div>
<!-- 메인 헤더 -->
<header>
<h1>{{ headerTitle }}</h1> <!-- 현재 화면에 따른 헤더 제목 -->
</header>
<!-- 메인 화면 -->
<MainView v-if="currentView === 'MAIN'" @changeView="changeView" />
<!-- 사용자 프로필 관리 화면 -->
<ProfileView v-if="currentView === 'PROFILE'" @close="goBack" />
<!-- 알림 관리 화면 -->
<NotificationView v-if="currentView === 'NOTIFICATION'" @close="goBack" />
</div>
</template>
<script>
import MainView from './components/MainView.vue';
import ProfileView from './components/ProfileView.vue';
import NotificationView from './components/NotificationView.vue';
export default {
components: {
MainView,
ProfileView,
NotificationView,
},
data() {
return {
currentView: "MAIN", // 초기 화면 설정
viewHistory: ["MAIN"], // 화면 전환 히스토리 기록
headerTitle: "", // 현재 화면에 따른 헤더 타이틀
};
},
methods: {
// 화면 전환, 새 화면을 history에 저장하고 헤더 제목을 업데이트
changeView(page) {
this.currentView = page; // 화면 전환 시 현재 화면을 전달받은 페이지로 변경
this.viewHistory.push(page); // viewHistory 배열에 새로운 화면을 추가
history.pushState({ component: "App", view: page }, ""); // 브라우저 history에 새로운 상태를 추가
this.updateHeaderTitle(); // 헤더 타이틀을 현재 화면에 맞게 업데이트
},
// 뒤로 가기, viewHistory에서 이전 화면으로 돌아감
goBack() {
if (this.viewHistory.length > 1) { // viewHistory에 두 개 이상의 화면이 있을 경우에만 실행
this.viewHistory.pop(); // viewHistory에서 가장 최근 화면을 제거
const previousView = this.viewHistory[this.viewHistory.length - 1]; // 이전 화면을 가져옴
this.currentView = previousView; // 현재 화면을 이전 화면으로 설정
history.back(); // 브라우저에서 '뒤로 가기' 처리
} else {
this.resetToMain(); // viewHistory가 한 개뿐이라면 메인 화면으로 리셋
}
this.updateHeaderTitle(); // 헤더 타이틀을 현재 화면에 맞게 업데이트
},
// 브라우저 뒤로/앞으로 가기 버튼 클릭 시 호출되는 이벤트 처리
handlePopState(event) {
if (event.state && event.state.component === "App") { // 이벤트의 상태가 유효하고, 해당 상태가 이 컴포넌트와 일치할 경우
this.currentView = event.state.view; // 현재 화면을 popstate 이벤트의 view로 설정
this.viewHistory.pop(); // viewHistory에서 가장 최근의 항목을 제거 (뒤로 가기 반영)
this.updateHeaderTitle(); // 헤더 타이틀을 현재 화면에 맞게 업데이트
} else if (this.currentView !== "MAIN") { // 이벤트가 유효하지 않거나 MAIN 화면이 아닌 경우
this.resetToMain(); // 화면을 메인으로 리셋
}
},
// 화면을 메인으로 리셋하고, viewHistory를 초기화
resetToMain() {
this.currentView = "MAIN"; // 현재 화면을 'MAIN'으로 설정
this.viewHistory = ["MAIN"]; // viewHistory를 'MAIN' 화면으로 초기화
history.pushState({ component: "App", view: "MAIN" }, ""); // 브라우저 history에 'MAIN' 상태를 추가
},
// 현재 화면에 따라 헤더 제목을 업데이트
updateHeaderTitle() {
switch (this.currentView) { // 현재 화면(currentView)에 따라
case "PROFILE":
this.headerTitle = "사용자 프로필 관리"; // 사용자 프로필 화면일 때
break;
case "NOTIFICATION":
this.headerTitle = "알림 관리"; // 알림 관리 화면일 때
break;
default:
this.headerTitle = ""; // 그 외의 경우에는 헤더 타이틀을 빈 문자열로 설정
}
},
},
mounted() {
window.addEventListener("popstate", this.handlePopState); // popstate 이벤트 리스너 추가
},
beforeDestroy() {
window.removeEventListener("popstate", this.handlePopState); // 컴포넌트가 제거될 때 popstate 이벤트 리스너 제거
},
};
</script>
<style scoped>
header {
background-color: #333;
color: white;
padding: 1rem;
text-align: center;
}
button {
margin: 10px;
padding: 10px;
font-size: 16px;
}
div {
text-align: center;
margin-top: 20px;
}
</style>
화면 전환 (changeView)
changeView 함수는 새로운 화면으로 전환하고,
해당 상태를 viewHistory 배열에 저장. 브라우저 히스토리에도 pushState를 이용해 상태를 기록함
뒤로 가기 (goBack)
goBack 함수는 viewHistory 배열에서 가장 최근 화면을 제거하고, 그 이전 화면으로 돌아감.
이때 history.back()을 호출하여 브라우저의 뒤로 가기 기능을 호출
브라우저의 뒤로 가기 이벤트 처리 (handlePopState)
사용자가 브라우저의 뒤로 가기 버튼을 눌렀을 때, popstate 이벤트가 발생.
이 이벤트를 처리하여 현재 화면을 적절하게 전환하고, viewHistory를 업데이트
요로코롬 해보았음
화면 전환 (changeView)
changeView 함수는 새로운 화면으로 전환할 때 호출됨 이 함수는 컴포넌트가 자체적으로 관리하는 히스토리인 viewHistory 배열에 현재 화면을 저장하고, 브라우저 히스토리에도 pushState()를 사용해 기록함
- viewHistory는 컴포넌트가 어떤 화면을 거쳐왔는지를 기억하는 역할
- pushState()는 브라우저의 뒤로 가기/앞으로 가기 버튼을 눌렀을 때 화면 전환이 일어나도록 브라우저에 상태를 저장
그래서 viewHistory.pop()은 컴포넌트가 기억하는 이전 화면으로 돌아가게 하고, history.back()은 브라우저의 뒤로 가기 기능을 통해 화면을 전환함. 두 기능은 함께 동작해서 사용자가 뒤로 가기를 눌렀을 때 컴포넌트와 브라우저 모두 상태를 일치시키는 역할을 함
event.state는 브라우저의 세션 히스토리(session history)에 저장됨
pushState()로 설정한 상태는 브라우저가 해당 페이지의 탭 세션 내에서 관리함. 즉, 브라우저의 탭이 유지되는 동안에만 유효함
브라우저를 닫거나 새로고침하면 이 정보는 사라짐. 세션이 끝날 때까지 상태가 유지되며, 새로고침 시에는 상태가 초기화됨
pushState()로 저장된 상태는 해당 탭에서만 유효합니다. 같은 URL이라도 다른 탭이나 윈도우에서는 동일한 상태를 공유하지 않음
제대로 돌아가긴하는데
아직 적절한 해결방안인지 여부는 모름 ㅡㅡ;
새로고침 후에도 굳이 이전 기록이 필요없기 때문에 더 처리 안해도 돼서 오히려 좋아. 했는데, 굳이 복구가 필요하다면 상태를 localStorage나 sessionStorage에 저장해두고 새로고침 시 복구하는 방식도 가능할듯......
'Vue' 카테고리의 다른 글
텍스트 내 삼항연산자 (0) | 2024.10.17 |
---|---|
브라우저 뒤로가기 버튼 막기 (0) | 2024.10.16 |
api 통신_콜백함수 & async/await (0) | 2024.09.09 |
Vue_12 컴포넌트간 데이터 전달(부모to자식, 자식to부모) (0) | 2024.09.06 |
Vue_11 <script></script> (0) | 2024.09.06 |