4 — 애플리케이션 제작 파트 — 라우터 기본

source: categories/study/vue-beginner-lv3/vue-beginner-lv3_4.md

4.1 라우터 설치 및 라우터 구현


npm i vue-router
# OR
yarn add vue-router

vue-router는 실제 서비스에 배포될 때도 필요한 라이브러리이기 때문에 package.json 상에서 dependencies에 명시가되어야한다.
때문에 위와 같은 명령어로 설치한다.

src/main.js 라우터 설정

import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";

Vue.config.productionTip = false

Vue.use(VueRouter);

const router = new VueRouter({
  routes: [
    // ...
    // router를 여기에 작성하면 router에 대한 정보가 많아졌을 때, main.js가 너무 router 편향적인 설정파일이 되겠죠.
    // main.js는 기본적으로 애플리케이션의 어떤 설정들.. 플러그인과 라이브러리 그리고 구조들을 파악할 수 있는.. 그런게 한눈에 들어오도록 하는 것이 좋습니다.
  ]
})

new Vue({
  render: h => h(App),
  router,
}).$mount('#app')

src/router/index.js 폴더 및 파일 생성 - 여기에 router 관리


vue-news/
|-- public/
|-- src/
|   |-- assets/
|   |-- components/
|   |-- router/
|   |   `-- index.js
|   |-- App.vue
|   `-- main.js
|-- .gitignore
|-- babel.config.js
|-- package.json
`-- vue.config.js

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            // path: url 주소
            path: '',
            // component: url 주소로 갔을 때 표시될 컴포넌트 ( 페이지단위라고 보면됨, 예를 들어서 MainPage 같은 페이지단위 컴포넌트 )
            component: '',
        },
        {
            path: '',
            component: '',
        },
        {
            path: '',
            component: '',
        }
    ]
})

export default router
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from "./router";

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router,
}).$mount('#app')

src/views/ 폴더 및 파일 생성 - 여기에 page 관리


vue-news/
|-- public/
|-- src/
|   |-- assets/
|   |-- components/
|   |-- router/
|   |   `-- index.js
|   |-- views/
|   |   |-- AskView.vue
|   |   |-- JobsView.vue
|   |   `-- NewsView.vue
|   |-- App.vue
|   `-- main.js
|-- .gitignore
|-- babel.config.js
|-- package.json
`-- vue.config.js

// src/router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import AskView from "../views/AskView";
import JobsView from "../views/JobsView";
import NewsView from "../views/NewsView";

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            // path: url 주소
            path: '/news',
            // component: url 주소로 갔을 때 표시될 컴포넌트 ( 페이지단위라고 보면됨, 예를 들어서 MainPage 같은 페이지단위 컴포넌트 )
            component: NewsView,
        },
        {
            path: '/ask',
            component: AskView,
        },
        {
            path: '/jobs',
            component: JobsView,
        }
    ]
})

export default router

4.2 router-view를 이용한 라우팅 컴포넌트 표시

src/App.vue



<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</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>


redirect - src/router/index.js



import Vue from "vue";
import VueRouter from "vue-router";
import AskView from "../views/AskView";
import JobsView from "../views/JobsView";
import NewsView from "../views/NewsView";

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            path: '/',
            redirect: '/news',
        },
        {
            // path: url 주소
            path: '/news',
            // component: url 주소로 갔을 때 표시될 컴포넌트 ( 페이지단위라고 보면됨, 예를 들어서 MainPage 같은 페이지단위 컴포넌트 )
            component: NewsView,
        },
        {
            path: '/ask',
            component: AskView,
        },
        {
            path: '/jobs',
            component: JobsView,
        }
    ]
})

export default router


src/components/ToolBar.vue 컴포넌트 파일 생성



<template>
<div>
  <!-- router-link 태그는 랜더링될 때 a 태그로 바뀐다. -->
  <router-link to="/news">News</router-link>
  <router-link to="/ask">Ask</router-link>
  <router-link to="/jobs">Jobs</router-link>
</div>
</template>

<script>
export default {
  name: "ToolBar"
}
</script>

<style scoped>

</style>


src/App.vue



<template>
  <div id="app">
    <tool-bar></tool-bar>
    <router-view></router-view>
  </div>
</template>

<script>
import ToolBar from "./components/ToolBar";

export default {
  name: 'App',
  components: {
    ToolBar,
  },
}
</script>

<style>

</style>


4.4 ToolBar의 라우터 링크 스타일링

src/App.vue



<template>
  <div id="app">
    <tool-bar></tool-bar>
    <router-view></router-view>
  </div>
</template>

<script>
import ToolBar from "./components/ToolBar";

export default {
  name: 'App',
  components: {
    ToolBar,
  },
}
</script>

<style>
body {
  padding: 0;
  margin: 0;
}
</style>


src/components/ToolBar.vue



<template>
<div class="header">
  <!-- router-link 태그는 랜더링될 때 a 태그로 바뀐다. -->
  <router-link to="/news">News</router-link> |
  <router-link to="/ask">Ask</router-link> |
  <router-link to="/jobs">Jobs</router-link>
</div>
</template>

<script>
export default {
  name: "ToolBar"
}
</script>

<style scoped>
.header {
  display: flex;
  padding: 8px;
  background-color: #42b883;
  color: #fff;
}
.header a {
  color: #fff;
}
.header .router-link-exact-active {
  color: #35495e;
}
</style>


4.5 [실습 안내] ItemView와 UserView 라우터 구현

src/views/ItemView.vue, src/views/UserView.vue 생성


vue-news/
|-- public/
|-- src/
|   |-- assets/
|   |-- components/
|   |-- router/
|   |   `-- index.js
|   |-- views/
|   |   |-- AskView.vue
|   |   |-- ItemView.vue
|   |   |-- JobsView.vue
|   |   |-- NewsView.vue
|   |   `-- UserView.vue
|   |-- App.vue
|   `-- main.js
|-- .gitignore
|-- babel.config.js
|-- package.json
`-- vue.config.js

src/router/index.js



import Vue from "vue";
import VueRouter from "vue-router";
import AskView from "../views/AskView";
import JobsView from "../views/JobsView";
import NewsView from "../views/NewsView";
import ItemView from "../views/ItemView";
import UserView from "../views/UserView";

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            path: '/',
            redirect: '/news',
        },
        {
            // path: url 주소
            path: '/news',
            // component: url 주소로 갔을 때 표시될 컴포넌트 ( 페이지단위라고 보면됨, 예를 들어서 MainPage 같은 페이지단위 컴포넌트 )
            component: NewsView,
        },
        {
            path: '/ask',
            component: AskView,
        },
        {
            path: '/jobs',
            component: JobsView,
        },
        {
            path: '/user',
            component: UserView,
        },
        {
            path: '/item',
            component: ItemView,
        }
    ]
})

export default router


4.6 라우터 폴더 작명 팁과 라우터 mode 안내

src/router 폴더이름을 src/routes로 변경


vue-news/
|-- public/
|-- src/
|   |-- assets/
|   |-- components/
|   |-- routes/
|   |   `-- index.js
|   |-- views/
|   |   |-- AskView.vue
|   |   |-- ItemView.vue
|   |   |-- JobsView.vue
|   |   |-- NewsView.vue
|   |   `-- UserView.vue
|   |-- App.vue
|   `-- main.js
|-- .gitignore
|-- babel.config.js
|-- package.json
`-- vue.config.js

해시값(#) 제거



import Vue from "vue";
import VueRouter from "vue-router";
import AskView from "../views/AskView";
import JobsView from "../views/JobsView";
import NewsView from "../views/NewsView";
import ItemView from "../views/ItemView";
import UserView from "../views/UserView";

Vue.use(VueRouter);

const router = new VueRouter({
    mode: 'history', // mode history가 아니라면 기본적으로 로컬서버 접속했을 때, locolhost:8080/#/ <- 이렇게 # 해시값이 붙어있게된다.
                     // # 해시값을 제거해주는 것이 mode history이다.
    routes: [
        {
            path: '/',
            redirect: '/news',
        },
        {
            // path: url 주소
            path: '/news',
            // component: url 주소로 갔을 때 표시될 컴포넌트 ( 페이지단위라고 보면됨, 예를 들어서 MainPage 같은 페이지단위 컴포넌트 )
            component: NewsView,
        },
        {
            path: '/ask',
            component: AskView,
        },
        {
            path: '/jobs',
            component: JobsView,
        },
        {
            path: '/user',
            component: UserView,
        },
        {
            path: '/item',
            component: ItemView,
        }
    ]
})

export default router