[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>

     

    ③ 완성화면

     

     

    반응형

    댓글