🔷 네트워크에서 경로를 선택하는 프로세스
🔷 SSR 에서의 Routing
🔷 CSR / SPA 에서의 Routing
🤔 만약 Routing 이 없다면?
💡 Vite 로 프로젝트 생성 시 Router 추가를 Yes로 설정한다.
서버 실행 후
🔷 Vue 프로젝트 구조 변화
1. App.vue 코드 변화
<template>
<div>
<h1>AppVue</h1>
<header>
<RouterLink to="/">Home</RouterLink>
<RouterLink :to="{name: 'home'}">HomeName</RouterLink>
<RouterLink to="/about">about</RouterLink>
<RouterLink :to="{name: 'about'}">aboutName</RouterLink>
</header>
<RouterView />
</div>
</template>
<script setup>
import { RouterView } from 'vue-router'
</script>
<style scoped>
header {
display: flex;
justify-content: space-around;
}
a {
text-decoration: none;
}
</style>
🔷 RouterLink
🔷 RouterView
2. router 폴더 생성
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
import UserView from '../views/UserView.vue'
//위에서 import한 생성 인자를 옵션으로 던지기
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
//URI: 경로/컴포넌트(views) 매핑
routes: [
{
path: '/',
name: 'home', //컴포넌트의 이름을 지정해 편하게 가져오기 위한 용도, 필수 아님
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView
},
{
path: '/user/:id', //동적 라우팅
name: 'user',
component: UserView
},
]
})
export default router
🔷 router/index.js
🔷 라우팅 기본
🔷 Named Routes
<RouterLink :to="{name: 'home'}">HomeName</RouterLink>
3. views 폴더 생성
🔷 views
❗ 일반 컴포넌트와 구분하기 위해 컴포넌트 이름을 View로 끝나도록 작성하는 것을 권장한다.
ex) 모든 사용자의 ID를 활용하여 프로필 페이지 URL을 설계한다면?
1. UserView 컴포넌트 라우트 등록
// index.js
import UserView from '../views/UserView.vue'
const router = createRouter({
routes: [
{
path: '/user/:id',
name: 'user',
component: UserView
},
]
})
2. 라우트의 매개변수는 컴포넌트에서 $route.params로 참조 가능
<!-- 아래와 같이 접근 가능하지만 권장 하지 않는다! -->
<p>{{$route.params.id}}</p>
3. 하지만 라우트의 매개변수는 다음과 같이 Composition API 방식으로 작성 하는 것을 권장
<template>
<div>
<h2>UserView</h2>
<!-- 아래와 같이 접근 가능하지만 권장 하지 않는다! -->
<p>{{$route.params.id}}</p>
<!-- 아래와 같은 작성을 권장 -->
<p>{{userId}}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router';
import { ref } from 'vue';
const route = useRoute();
const userId = ref(route.params.id);
</script>
<style scoped>
</style>
💡 userId 변경 시에 변경된 value가 바로 적용되게 하기 위해서 watch()
를 사용한다.
watch(() => route.params.id, (newId) => {
userId2.value = newId;
});
<!-- 아래와 같이 접근 가능하지만 권장 하지 않는다! -->
<p>{{$route.params.id}}</p>
<!-- 아래와 같은 작성을 권장 -->
<p>{{userId}}</p>
<!-- value 즉시 변경 적용 -->
<p>{{userId2}}</p>
bzeromo 에서 gue로 이동 시 userId2는 바로 변경이 적용되었다.
이 방법 외에도 onBeforeRouteUpdate()
를 이용하는 방법이 있는데 이는 잠시후에 알아본다.
🔷 router 의 인스턴스 메서드를 사용해 RouterLink로 a 태그를 만드는 것처럼 프로그래밍으로 네비게이션 관련 작업을 수행할 수 있음
1. 다른 위치로 이동 하기 → router.push()
router.push()
를 호출하는 것과 같음//컴포넌트 이동
const router = useRouter();
const goHome = function() {
//router.push('/');
router.push({name: 'home'})
// literal string path
//router.push('/users/alice')
// object with path
//router.push({ path: '/users/alice' })
// named route with params to let the router build the url
//router.push({ name: 'user', params: { username: 'alice' } })
// with query, resulting in /register?plan=private
//router.push({ path: '/register', query: { plan: 'private' } })
}
<button @click="goHome">홈으로</button>
2. 현재 위치 바꾸기 → router.replace()
const router = useRouter();
const goHome = function() {
router.replace({name: 'home'})
}
🔷 Vue router 를 통해 특정 URL에 접근할 때 다른 URL로 redirect를 하거나 취소하여 네비게이션을 보호
ex) 로그인이 되어있는데 굳이 링크에 /login을 추가해 어떻게든 다시 로그인 페이지로 넘어가려는 악의 추종자들이 있다... 🤦♂️
🔷 Navigation Guard 종류
🔷 router.beforeEach()
router.beforeEach((to, from) => {
// console.log(to)
// console.log(from)
//전역 가드(Globally Guard)
if (!isAuth && to.name != 'login') {
console.log("로그인이 필요합니다.")
return { name: "login" };
}
})
로그인 전(isAuth가 false일 때)에는 다른 페이지로 이동할 수가 없다.
false
Route Location
router.push()
를 호출하는 것처럼 경로 위치를 전달하여 다른 위치로 redirect💡 return 이 없다면 ’to’ URL Route 객체로 이동한다.
🔷 router.beforeEnter()
{
path: '/login',
name: 'login',
component: LoginView,
//Per-route Guard
beforeEnter: (to, from) => {
if (isAuth) {
console.log("이미 로그인 하셨습니다.");
return { name: 'home' };
}
}
},
로그인 상태일 때 로그인 뷰로 넘어갈 수 없게끔 막혔다.
🔷 onBeforeRouteLeave
onBeforeRouteLeave(() => {
const answer = confirm("정말 나갈거임?");
if (!answer) return false;
});
userView에서 다른 뷰로 이동 시에 자동으로 팝업이 뜨며, 확인을 누르면 이동한다.
💡
window.confirm()
팝업을 띄워 확인 시 true, 취소 시 false를 반환한다.
🔷 onBeforeRouteUpdate
onBeforeRouteUpdate((to) => {
userId.value = to.params.id;
})
이제 유저 정보가 갱신되면 모든 컴포넌트가 이를 즉각 반영한다.
Router 개념은 다시 봐도 복잡해~