[Vue] Router를 이용해서 페이지 전환하기

 

01. Vue Router

 

01) Router

  • 라운터는 브라우저에서 웹 페이지 이동할 때 화면을 전환하는 기능
  • 페이지를 이동할 때 서버에 요청하여 새로 갱신하는 것이 아니라 미리 해당 페이지를 받아 화면을 바꾸는 것 (=Single Page Application)
  • 라우팅을 이용하면 화면 간의 전환을 매끄럽게 할 수 있음
  • 뷰에서는 라우팅 기능을 지원해 주는 라이브러리가 있음
  • 뷰 라우터는 브라우저를 새로고침하지 않고 페이지끼리 자유롭게 이동할 수 있음
  • 페이지를 이동할 때, 변경된 요소의 영역에 컴포넌트를 갱신해 줌

 

02) Vue Router 설치

​npm install --save vue-router

 

 

02. 새로운 프로젝트 생성

 

① 터미널에 'vue create sep14' 입력하기

vue create sep14

 

 

② 뷰 파일이 생성되면 파일 열고 뷰 터미널에서 'npm run serve' 입력하기

 

③ src안에 router, views 폴더 만들고 각각 폴더 안에 파일 생성하기

 

 

03. vue 파일 생성

 

① IndexPage.vue

<template> ​​​​<div class="index"> ​​​​​​<h1>index</h1> ​​​​​​<h2>index</h2> ​​​​</div> </template> <script> </script> <style> </style>

 

② JoinPage.vue

<template> ​​​​<div class="join"> ​​​​​​​<h1>join</h1> ​​​​​</div> </template> <script> </script> <style> </style>

 

③ LoginPage.vue

<template> ​​​​<div class="login"> ​​​​</div> </template> <script> </script> <style> </style>

 

 

④ MainPage.vue

<template> ​​​​<div class="main"> ​​​​</div> </template> <script> </script> <style> </style>

 

⑤ BoardList.vue

<template> ​​<div> ​​​​<table border="1"> ​​​​​​<tr> ​​​​​​​​<td>번호</td> ​​​​​​​​<td>제목</td> ​​​​​​​​<td>글쓴이</td> ​​​​​​​​<td>날짜</td> ​​​​​​​​<td>읽음</td> ​​​​​​</tr> ​​​​​​<tr v-for="n in list" v-bind:key="n.boardNo"> ​​​​​​​​<td>{{ n.boardNo }}</td> ​​​​​​​​<td>{{ n.title }}</td> ​​​​​​​​<td>{{ n.writer }}</td> ​​​​​​​​<td>{{ n.date }}</td> ​​​​​​​​<td>{{ n.read }}</td> ​​​​​​</tr> ​​​​</table> ​​</div> </template> <script> export default { ​​name: "BoardList", ​​data() { ​​​​return { ​​​​​​list: [ ​​​​​​​​{ ​​​​​​​​​​boardNo: 10, ​​​​​​​​​​title: "10 번글", ​​​​​​​​​​writer: "홍길동", ​​​​​​​​​​date: "20230525", ​​​​​​​​​​read: 15 ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 9, ​​​​​​​​​​title: "9 번글", ​​​​​​​​​​writer: "김길동", ​​​​​​​​​​date: "20230524", ​​​​​​​​​​read: 16 ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 8, ​​​​​​​​​​title: "8 번글", ​​​​​​​​​​writer: "최길동", ​​​​​​​​​​date: "20230523", ​​​​​​​​​​read: 17, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 7, ​​​​​​​​​​title: "7 번글", ​​​​​​​​​​writer: "강길동", ​​​​​​​​​​date: "20230522", ​​​​​​​​​​read: 18, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 6, ​​​​​​​​​​title: "6 번글", ​​​​​​​​​​writer: "임길동", ​​​​​​​​​​date: "20230521", ​​​​​​​​​​read: 19, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 5, ​​​​​​​​​​title: "5 번글", ​​​​​​​​​​writer: "정길동", ​​​​​​​​​​date: "20230520", ​​​​​​​​​​read: 20, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 4, ​​​​​​​​​​title: "4 번글", ​​​​​​​​​​writer: "광길동", ​​​​​​​​​​date: "20230519", ​​​​​​​​​​read: 21, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 3, ​​​​​​​​​​title: "3 번글", ​​​​​​​​​​writer: "이길동", ​​​​​​​​​​date: "20230518", ​​​​​​​​​​read: 22, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 2, ​​​​​​​​​​title: "2 번글", ​​​​​​​​​​writer: "박길동", ​​​​​​​​​​date: "20230517", ​​​​​​​​​​read: 23, ​​​​​​​​}, ​​​​​​​​{ ​​​​​​​​​​boardNo: 1, ​​​​​​​​​​title: "1 번글", ​​​​​​​​​​writer: "양길동", ​​​​​​​​​​date: "20230516", ​​​​​​​​​​read: 24, ​​​​​​​​}, ​​​​​​], ​​​​}; ​​}, }; </script> <style scoped> table { ​​width: 800px; ​​height: 300px; ​​border-collapse: collapse; ​​margin: 0 auto; } th { ​​background-color: rgb(169, 109, 109); } td { ​​border-bottom: 1px gray solid; } tr:hover { ​​background-color: gray; ​​color: white; } .title { ​​text-align: left; } #td1 { ​​width: 10%; } #td2 { ​​width: 20%; } </style>

 

⑥ components > MenuPage.vue 생성

<template> ​​<header> ​​​​<nav class="nav"> ​​​​​​<ul> ​​​​​​​​<li><router-link to="/">index</router-link></li> ​​​​​​​​<li><router-link to="/main">main</router-link></li> ​​​​​​​​<li><router-link to="/boardList">게시판</router-link></li> ​​​​​​​​<li class="lir"><router-link to="/join">join</router-link></li> ​​​​​​​​<li class="lir"><router-link to="/login">login</router-link></li> ​​​​​​</ul> ​​​​</nav> ​​</header> </template> <script> export default { ​​name: "MenuPage", }; </script> <style> /* nav를 fixed로 하였기 때문에 높이를 높여 영역을 확보 */ header { ​​height: 50px; } nav { ​​position: fixed; ​​top: 0; ​​width: 100%; ​​height: 30px; ​​background-color: gray; } nav ul { ​​margin: 0; ​​padding: 0; } nav li { ​​list-style: none; ​​float: left; ​​width: 100px; ​​height: 30px; ​​line-height: 30px; ​​text-align: center; } nav li:hover { ​​font-weight: bold; } a { ​​text-decoration: none; ​​color: white; } .lir { ​​float: right; ​​width: 80px; } </style>

 

 

04. 라우팅

 

01) 라우터 구성

🔎 라우터의 구성은 RouteRecordRaw의 배열인데 이는 URL과 Component의 관계를 정의함

🔎 RouteRecordRaw의 속성

  •  path : 들어오는 URL로, 콜론(;)으로 시작하는 값은 매개변수를 의미함.
    (예시: '/application/:app-name'으로 호출했다면 'this.$route.params.appName'으로 접근할 수 있음
  • redirect : path로 들어온 URL을 다른 URL로 전달할 때 사용
  • alias : redirect랑 비슷하지만 URL을 복제가 아닌 참조 개념
  • name : path의 이름을 설정 
  • beforeEnter : 네비게이션 가드를 입력받아 라우팅이 실제로 발생되기 전에 호출함
    (네비게이션 가드는 라우팅이 일어날 때 라우팅 취소, 경로 우회 등의 행위를 위한 것으로 to, from, next 3개의 매개변수를 가짐)
  • props : router-view의 전달인자를 속성으로 변경시켜줌
  • meta : 사용자가 원하는 메타 정보를 입력하게 하고 이는 네비게이션 가드에서 to.meta.META_KEY 형식으로 불러 사용할 수 있음
  • children : 하위 URL에 대한 라우터를 구성함

02) 페이지 이동 방법

🔎 <router-link>

  • 앵커 <a> 태그를 이용해 만들어진 태그로 일반적으로 to라는 속성을 입력받음
  • 문자열로 전달해도 되고 params에 전달인자 등을 전달할 수 있음
  • to 속성의 속성값 : path, name, params, query
  • replace 속성을 추가하면 히스토리에 경로가 남지 않아 백스페이스키를 눌렀을 때 현재 페이지로 돌아올 수 없음
<router-link to="/foo">FOO</router-link> <router-link :to="{ name: 'FOO', params: { foo: 'bar' }}">FOO</router-link> <router-link to="/foo" replace>Foo</router-link>

 

🔎 push

  • 스크립트 코드를 이용한 라우팅
  • replace가 없는 <router-link> to 속성과 같음
  • 히스토리에 현재 페이지를 저장하고 다음 링크로 이동

🔎 replace

  • replace 속성을 <router-link>에 넣은 것과 동일함
  • 히스토리에 현재 페이지를 저장하지 않고 이동함

03) index.js

/* 실제로 라우팅을 해주는 파일. 이곳에서 각 파일로 연결시켜 줍니다. */ import { createRouter, createWebHistory } from "vue-router"; import indexPage from "@/views/IndexPage.vue"; import boardList from "@/views/BoardList.vue"; import mainPage from "@/views/MainPage.vue"; import loginPage from "@/views/LoginPage.vue"; import joinPage from "@/views/JoinPage.vue"; const routes = [ ​​{ path: "/", name: "index", component: indexPage }, ​​{ path: "/join", name: "join", component: joinPage }, ​​{ path: "/boardList", name: "boardList", component: boardList }, ​​{ path: "/main", name: "main", component: mainPage }, ​​{ path: "/login", name: "login", component: loginPage }, ]; const router = createRouter({ ​​history: createWebHistory(process.env.BASE_URL), ​​routes, }); export default router;

 

 

05. 화면 전환하기

 

① main.js 수정

import { createApp } from 'vue' import App from './App.vue' import router from './router' const app = createApp(App) app.use(router).mount('#app')

 

② main.js 수정

<template> ​​<MenuPage></MenuPage> ​​<router-view></router-view> </template> <script> import MenuPage from './components/MenuPage.vue'; export default { ​​name: 'App', ​​components: { ​​​​MenuPage ​​} } </script> <style> #app { ​​font-family: Avenir, Helvetica, Arial, sans-serif; ​​-webkit-font-smoothing: antialiased; ​​-moz-osx-font-smoothing: grayscale; ​​text-align: center; ​​color: #2c3e50; ​​margin-top: 60px; } </style>

 

③ 완성화면

 

 

댓글