네트워크에서 경로를 선택하는 프로세스
▷ 웹 애플리케이션에서 다른 페이지 간의 전환과 경로를 관리하는 기술
유저가 URL을 통한 페이지의 변화를 감지할 수 없음
페이지가 무엇을 렌더링 중인지에 대한 상태를 알 수 없음
브라우저의 뒤로 가기 기능을 사용할 수 없음
▷ 페이지는 1개이지만, 주소에 따라 여러 컴포넌트를 새로 렌더링하여 마치 여러 페이지를 사용하는 것처럼 보이도록 해야 함
Vue 공식 라우터
(The official Router for Vue.js)
<a> 태그를 렌더링// template 태그 안
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
<template>
<header>
</header>
<RouterView />
</template>
⇒ 예시는 헤더 아래에 배치

RouterView 위치에 렌더링 할 컴포넌트를 배치
기존 components 폴더와 기능적으로 다른 것은 없으며 단순 분류의 의미로 구성됨
※ 일반 컴포넌트와 구분하기 위해 컴포넌트 이름을 view로 끝나도록 작성하는 것을 권장

index.js에 라우터 관련 설정 작성(주소, 이름, 컴포넌트)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
]
})
RouterLink의 ‘to’ 속성으로 index.js에서 정의한 주소 값(path)을 사용
<!-- App.vue -->
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
RouterLink 클릭 시 경로와 일치하는 컴포넌트가 RouterView에서 렌더링 됨
<!-- App.vue -->
<RouterView />
경로에 이름을 지정하는 라우팅
https://router.vuejs.org/guide/essentials/named-routes.html
<!-- App.vue -->
<RouterLink :to="{name:'home'}">Home</RouterLink>
<RouterLink :to="{name:'user', params:{'id': userId}}" >User</RouterLink>
user/1
user/2
user/3
▷ 일정한 패턴의 URL 작성을 반복해야 함
<template>
<div>
<h1>Userview</h1>
</div>
</template>
매개변수는 콜론(”:”)으로 표기
▷ UserView 컴포넌트 라우트 등록
//index.js
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path:'/user/:id',
name:'user',
component:UserView,
}
]
})
매개변수는 객체의 params 속성의 객체 타입으로 전달
단, 객체의 key 이름과 index.js에서 지정한 매개변수 이름이 같아야 함
▷ UserView 컴포넌트로 이동하기 위한 RouterLink 작성
<!-- App.vue -->
<script setup>
import {ref} from 'vue'
const userId = ref(1)
</script>
<template>
<RouterLink :to="{name:'user', params:{'id': userId}}" >User</RouterLink>
</template>
경로가 일치하면 라우트의 매개변수는 컴포넌트에서 $route.params로 참조 가능
▷ 현재 사용자의 id를 출력하기
<template>
<div>
<h1>Userview</h1>
<h2>{{ $route.params.id }}번 User페이지</h2>
<h2>{{ userId }}번 User 페이지</h2>
</div>
</template>
useRoute( ) 함수를 사용해 스크립트 내에서 반응형 변수에 할당 후 템플릿에 출력하는 것을 권장
<template>
<div>
<h1>Userview</h1>
<h2>{{ userId }}번 User 페이지</h2>
</div>
</template>
<script setup>
import {ref} from 'vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const userId = ref(route.params.id)
</script>
<style lang="scss" scoped>
</style>
중첩된 라우팅
https://router.vuejs.org/guide/essentials/nested-routes.html#Nested-Routes
컴포넌트 생성
▷ components 폴더에 UserProfile, UserPosts 컴포넌트 작성
vue가 아니라 component에 작성하는 이유는 ?
<!-- UserProfile.vue -->
<template>
<div>
<h1>UserProfile</h1>
</div>
</template>
<!-- UserPosts.vue -->
<template>
<div>
<h1>UserPosts</h1>
</div>
</template>
라우터 등록
▷ index.js에 두 컴포넌트를 import
import UserProfile from '@/components/UserProfile.vue'
import UserPosts from '@/components/UserPosts.vue'
작성할때 path앞에 슬래시를 붙이면 안된다.
//index.js
{
path:'/user/:id',
name:'user',
component:UserView,
children : [
{path : 'profile', name:'user-profile',component:UserProfile},
{path : 'posts', name:'user-posts', component:UserPosts}
]
}
UserView에서 작성한다.(children의 부모뷰에서 작성한다)
<template>
<div>
<RouterLink :to="{name:'user-profile'}">Profile</RouterLink>
<RouterLink :to="{name:'user-posts'}">Posts</RouterLink>
<h1>Userview</h1>
<h2>{{ userId }}번 User 페이지</h2>
<hr>
<RouterView />
</div>
</template>
{
path:'/user/:id',
// name:'user',
component:UserView,
children : [
{path : '', name:'user',component:UserHome},
{path : 'profile', name:'user-profile',component:UserProfile},
{path : 'posts', name:'user-posts', component:UserPosts}
]
}<template>
<div>
<h1>UserHome</h1>
</div>
</template>RouterLink 대신 JavaScript를 사용해 페이지를 이동하는 것
https://router.vuejs.org/guide/essentials/navigation.html#Programmatic-Navigation
<a> 태그를 만드는 것처럼 프로그래밍으로 네비게이션 관련 작업을 수행할 수 있음다른 위치로 이동하기
(Navigate to a differnt location)
<template>
<div>
<button @click="goHome">Home</button>
<RouterLink :to="{name:'user'}">Home</RouterLink>
<RouterLink :to="{name:'user-profile'}">Profile</RouterLink>
<RouterLink :to="{name:'user-posts'}">Posts</RouterLink>
<h1>Userview</h1>
<h2>{{ userId }}번 User 페이지</h2>
<hr>
<RouterView />
</div>
</template>
<script setup>
import {useRoute, useRouter} from 'vue-router'
const router = useRouter()
const goHome = function(){
router.push({name:'home'})
}
</script>⇒ 자바스크립트를 이용해 페이지 전환하는게 가능해졌다는 이야기
현재 위치 바꾸기
(Replace current location)
const goHome = function(){
// router.push({name:'home'})
router.replace({name:'home'})
}
▷ 라우트 전환 전/후 자동으로 실행되는 Hook
https://router.vuejs.org/guide/advanced/navigation-guards.html
애플리케이션 전역에서 동작하는 가드
▷ 작성위치 : index.js
다른 URL로 이동하기 직전에 실행되는 함수
(Global Before Guards)
router.beforeEach((to, from) =>{
return false 또는 return{name:'About'}
//만약 return을 명시적으로 써주지않으면 return값은 to
})
//index.js
// 이동할때마다 함수가 호출된다.
router.beforeEach((to,from)=>{
console.log(to)
console.log(from)
})
export default router
▷ to에는 이동할 URL인 user 라우트에 대한 정보가,
from에는 현재 URL인 home 라우트에 대한 정보가 들어있음
<template>
<div>
<h1>Login View</h1>
</div>
</template>
{
path:'/login',
name:'login',
component:LoginView,
},
<RouterLink :to="{name:'login'}" >Login</RouterLink>
```jsx
router.beforeEach((to,from)=>{
const isAuthenticated = false
// 로그인 되어있지 않고 이동하는 곳이 login페이지가 아니라면
if (!isAuthenticated && to.name !== 'login'){
console.log('로그인이 필요합니다.')
return {name:'login'}
}
})
```⇒ 모든 이동에 대한 것은 전역 가드를 통해 조절하면 된다.
특정 라우터에서만 동작하는 가드
▷ 작성위치 : index.js의 각 routes
특정 route에 진입했을 때만 실행되는 함수
▷ 단순히 URL의 매개변수나 쿼리 값이 변경될 때는 실행되지 않고,
다른 URL에서 탐색해 올 때만 실행됨
{
path:'/user/:id',
// name:'user',
component:UserView,
beforeEnter : (to,from) =>{
return false
}
},
{
path:'/user/:id',
// name:'user',
component:UserView,
beforeEnter : (to,from) =>{
console.log(to)
console.log(from)
}
},
“이미 로그인 한 상태라면 LoginView 진입을 막고 HomeView로 이동 시키기”
▷ 전역 가드 beforeEach 관련 코드는 주석 처리 후 진행
로그인 상태라면 Homeview로 이동
로그인 상태가 아니라면 LoginView로 이동
const isAuthenticated = true
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path:'/login',
name:'login',
component:LoginView,
beforeEnter : (to,from)=>{
if (isAuthenticated)===true{
console.log('이미 로그인 상태입니다.')
return {name:'home'}
}
}
},
]
})
특정 컴포넌트 내에서만 동작하는 가드
▷ 작성위치 : 각 컴포넌트의
현재 라우트에서 다른 라우트로 이동하기 전에 실행
▷ 사용자가 현재 페이지를 떠나는 동작에 대한 로직을 처리
이미 렌더링 된 컴포넌트가 같은 라우트 내에서 업데이트 되기 전에 실행
▷ 라우트 업데이트 시 추가적인 로직을 처리
onBeforeRouteLeave((to,from)=>{
const answer = window.confirm('정말 떠나실건가요?')
if (answer === false){
return false
}
})
“UserView 페이지에서 다른 id를 가진 User의 UserView 페이지로 이동하기”
▷ 같은 라우트 내에서 업데이트 되는 경우 (/user/1 → /user/100)
<template>
<div>
<button @click="routeUpdate">100번 유저 페이지</button>
<h1>Userview</h1>
<h2>{{ userId }}번 User 페이지</h2>
<hr>
<RouterView />
</div>
</template>
<script setup>
import {ref} from 'vue'
import {onBeforeRouteUpdate} from 'vue-router'
const userId = ref(route.params.id)
const routeUpdate = function(){
router.push({name:'user',params:{id:100}})
}
onBeforeRouteUpdate((to,from)=>{
userId.value = to.params.id
})
</script>
onBeforeRouteUpdate에서 userId를 변경하지 않으면 userId는 갱신되지 않음
▷ 컴포넌트가 재사용되었기 때문
▷ 앱을 빌드할 때 처음부터 모든 컴포넌트를 준비하면
컴포넌트의 크기에 따라 페이지 로드 시간이 길어질 수 있기 때