반응형
오늘은 뷰를 쓰면서 무조건 써야하는 뷰 라우터에 대해 알아보겠다!
아 참고로 뷰3 기준으로 최대한 작성 할거다
Routing
- 네트워크에서 경로를 선택하는 프로세스
- 웹 서비스에서의 라우팅
- 유저가 방문한 URL에 대해 적절한 결과를 응답하는 것
- Server가 모든 라우팅을 통제
- URL로 요청이 들어오면 응답으로 완성된 HTML 제공
- 결론적으로, Routing(URL)에 대한 결정권을 서버가 가짐
- Why routing?
- 그럼 동작에 따라 URL이 반드시 바뀌어야 하나? => 그렇지는 않다! 단 유저의 사용성 관점에서는 필
- Routing이 없다면
- 유저가 URL을 통한 페이지의 변화를 감지할 수 없음
- 페이지가 무엇을 렌더링 중인지에 대한 상태를 알 수 없음
- 새로고침 시 처음 페이지로 돌아감
- 링크를 공유할 시 처음 페이지만 공유 가능
- 브라우저의 뒤로 가기 기능을 사용할 수 없음
Vue Router
- Vue의 공식 라우터
- SPA 상에서 라우팅을 쉽게 개발할 수 있는 기능을 제공
- 라우트(routes)에 컴포넌트를 매핑한 후, 어떤 URL에서 렌더링 할지 알려줌
- 즉, SAP를 MPA처럼 URL을 이동하면서 사용 가능
- SPA의 단점 중 하나인 "URL이 변경되지 않는다."를 해결
- MPA(Multiple Page Application)
- 여러 개의 페이지로 구성된 애플리케이션
- SSR 방식으로 렌더링
시작하기
- 뷰 프로젝트를 성성하고
- $vue add router 를 입력하면 된다(뷰2에선 이거 하면 된다)
- $vue add vue-router@next (뷰3에선 이거 해라)
- 근데 보통 요즘은 프로젝트 생성할때 라우터까지 생성 할거냐고 물어보거나 알아서 생성해주는게 많은거 같다
import { createRouter, createWebHistory } from "vue-router";
// 연결할 각 컴포넌트 import (보통 src/views폴더 아래 컴포넌틑들 생성해둠 )
import HelloWorld from '../components/HelloWorld.vue'
import MyComponent from '../components/MyComponent.vue'
// 라우터 설계
const routes = [
{ path: '/', component:HelloWorld}, //메인 홈화면
{ path: '/1', component:MyComponent },
]
// 라우터 생성
const router = createRouter({
history: createWebHistory(),
routes
});
// 라우터 추출(main.js에서 import)
export {router}
- 뷰라우터 사용은 main.js에서 use를 통해 할 수 있다. 메인 뷰파일에 템플릿에는 <router-view>태그를 통해 경로에 따라 다른 컴포넌트들이 올 수 있게 한다.
import { createApp } from 'vue'
import App from './App.vue'
// 생성한 뷰 라우터 받아오기
import { router } from './router/index.js'
const app = createApp(App)
app.use(router) // 라우터 사용
app.mount('#app')
근데 내가 요즘 만들고 있는 프로젝트는 뷰티파이로 시작을 했는데 어쨌든 main.js 를 들어가서 봤더니 use(router)가 없는게 아닌가!!!
뭐여 어캐 근데 에러 안나고 되는거지?
그래서 좀 찾아보니까
뷰티파이로 일단 프로젝트를 생성하면 Vite가 포함된고 또 plugins 파일도 만들어 지는데
쨌든 플러그인 파일 안에 있는 index.js에 use(router)가 있었고 그거 덕분에 잘 작동을 한거였다
정말 혹시나 나같은 경우가 있다면 참고하길 바란다
- src/App.vue
<template>
<div id="app">
<!-- uri에 따라 해당 컴포넌트가 router-view를 대신함 -->
<router-view></router-view>
</div>
</template>
- router-link
- a 태그와 비슷한 기능 => URL을 이동시킴
- routes에 등록된 컴포넌트와 매핑됨
- 히스토리 모드에서 router-link는 클릭 이벤트를 차단하여 a 태그와 달리 브라우저가 페이지를 다시 로드 하지 않도록 함
- 목표 경로는 'to'속성으로 지정됨
- 기능에 맞게 HTML에서 a태그로 rendering 되지만, 필요에 따라 다른 태그로 바꿀 수 있음
<router-link :to="{ name: 'home' }">Home</router-link>
- a 태그와 비슷한 기능 => URL을 이동시킴
- router-view
- 주어진 URL에 대해 일치하는 컴포넌트를 렌더링 하는 컴포넌트
- 실제 component가 DOM에 부착되어 보이는 자리를 의미
- router-link를 클릭하면 routes에 매핑된 컴포넌트를 렌더링.
- src/router/index.js
- 라우터에 관련된 정보 및 설정이 작성 되는 곳
- routes에 URL과 컴포넌트를 매핑
import Vue from 'vue'
import VueRouter from 'vue-router'
import IndexView from '../views/IndexView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'index',
component: IndexView
},
]
- src/Views
- router-view에 들어갈 component 작성
- 각 폴더 안에 .vue파일들이 기능적으로 다른 것은 아님
- 폴더별 컴포넌트 배치는 다음과 같이 진행
- views/
- routes에 매핑되는 컴포넌트, 즉 <router-view>의 위치에 렌더링 되는 컴포넌트를 모아두는 폴더
- 다른 컴포넌트와 구분하기 위해 View로 끝나도록 만드는 것을 권장
- components/
- routes에 매핑된 컴포넌트의 하위 컴포넌트를 모아두는 폴더
- views/
주소를 이동하는 2가지 방법
1. 선언적 방식 네비게이션
- 선언적 방식 네비게이션
- router-link의 'to'속성으로 주소 전달
- routes에 등록된 주소와 매핑된 컴포넌트로 이동
// App.vue
<template>
<div id="app">
<nav>
<router-link :to="{ name: 'home' }">Home</router-link> |
<router-link :to="{ name: 'about' }">About</router-link> |
</nav>
<router-view/>
</div>
</template>
- Named Routes
- 이름을 가지는 routes
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
]
- 동적인 값을 사용하기 때문에 v-bind를 사용해야 정상적으로 작동 (to가 아니라 :to로 써야함)
2. 프로그래밍 방식 네비게이션
- 프로그래밍 방식 네비게이션
- Vue 인스턴스 내부에서 라우터 인스턴스에 $router로 접근 할 수 있음
- 다른 URL로 이동하려면 router.push를 사용
- history stack에 이동할 URL을 넣는(push) 방식
- history stack에 기록이 남기 때문에 사용자가 브라우저의 뒤로 가기 버튼을 클릭하면 이전 URL로 이동할 수 있음
- 결국 <router-link :to="...">을 클릭하는 것과 $router.push(...)를 호출하는 것은 같은 동작
동적라우팅
- Dynamic Route Matching
- 동적 인자 전달
- URL의 특정 값을 변수처럼 사용할 수 있음
- 동적 인자 전달
// router/index.js
import HelloView from '@/views/HelloView.vue'
const routes =[
...,
{
path: '/hello/:userName',
name: 'hello',
component: HelloView
}
]
- $route.params로 변수에 접근 가능
// views/HelloView.vue
<template>
<div>
<h1>hello, {{ $route.params.userName }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloView',
}
</script>
- Dynamic Route Matching - 선언적 방식 네비게이션
- params를 이용하여 동적 인자 전달 가능
// App.vue
<template>
<div id="app">
<nav>
<router-link :to="{ name: 'home' , params: { userName: 'harry' }}">Home</router-link> |
<router-link :to="{ name: 'about' }">About</router-link> |
</nav>
<router-view/>
</div>
</template>
Lazy-loading
- route에 컴포넌트를 등록하는 또다른 방법
- 모든 파일을 한 번에 로드하려고 하면 모든 걸 다 읽는 시간이 매우 오래 걸림
- 미리 로드를 하지 않고 특정 라우트에 방문할 때 매핑된 컴포넌트의 코드를 로드하는 방식을 활용할 수 있음
- 모든 파일을 한 번에 로드하지 않아도 되기 때문에 최초에 로드하는 시간이 빨라짐
- 당장 사용하지 않을 컴포넌트는 먼저 로드하지 않는 것이 핵심
- Lazy-loading
// router/index.js
const routes = [
{
path: '/about',
name: 'about',
component: () => import('../views/AboutView.vue'),
}
]
네비게이션 가드
- beforeEnter
- 여러 라우터를 타고 다닐때 로그인한 유저(권한이 있는)만 해당 path 로 들어가게 하려면 라우터에서 생성되기 전에 체크를 해주면 된다!
- 이 훅이 바로 beforeEnter 이다.
import Vue from 'vue';
import store from '../store/index';
import Router from 'vue-router';
import Home from '@/components/Login';
import RoomList from '@/components/RoomList';
Vue.use(Router);
const requireAuth = () => (to, from, next) => {
if (store.state.accessToken !== '') {
return next();
}
next('/login');
};
export default new Router({
mode: 'history',
routes: [
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/roomlist',
name: 'RoomList',
component: RoomList,
beforeEnter: requireAuth()
},
...]
})
- 이런식으로 해주면 스토어에 accessToken이 있을때만 next()를 하고 아니면 로그인으로 보낸다.
오늘은 뷰 라우터에 대해 알아봤다
뷰로 프로젝트 하면 안쓸수가 없는놈이라 잘 공부해 보시길...
반응형
'개발💻 > Vue' 카테고리의 다른 글
[Vue] Vue 정리하기(6) - Vue3 composition api 2편 (setup, ref) (45) | 2023.09.19 |
---|---|
[Vue] Vue 정리하기(5) - Vue3 composition api 1편 (0) | 2023.09.18 |
[Vue] Vue 정리하기(3) - Vuex (1) | 2023.09.14 |
[Vue] Vue 정리하기(2) - Vue Directive (0) | 2023.09.14 |
[Vue] Vue 정리하기(1) - Vue CLI, Component (0) | 2023.09.14 |