Vue

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

PEAZH 2023. 9. 14. 14:25
반응형

 

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>

 

③ 완성화면

 

 

반응형