Vue3

vue-router

덕구공 2022. 10. 20. 12:33

공식문서

https://router.vuejs.org/

 

Vue Router

 

router.vuejs.org

설치

  • vue-router를 사용할 프로젝트에 설치!
// npm
npm install vue-router

// yarn
yarn add vue-router

vue-router 사용해보기

1. 라우팅을 적용할 만들기

  • 라우팅을 적용할 컴포넌트를 만들어보자!
  • 나는 "/", "/chicken", "/duckgugong" 경로에 적용할 컴포넌트를 각각 Home, Chicken, Duckgugong 이라고 만들었다!

components/Home.vue

<template>
  <h1>This is "Home" Component</h1>
</template>

components/Chicken.vue

<template>
  <h1>I'm "Chicken" Component</h1>
</template>

components/Duckgugong.vue

<template>
  <h1>I'm "Duckgugong" Component</h1>
</template>


2. main.js에 라우터 설정하기

  • main.js 파일을 열고 아래와 같이 라우터를 설정해보자!

 

  • 우선 라우팅에 필요한 라이브러리와 컴포넌트들을 불러오자
import { createApp } from 'vue'
// 1. createWebHistory, createRouter 불러오기
import { createWebHistory, createRouter } from 'vue-router'
import App from './App.vue'
// 2. 라우팅할 컴포넌트 불러오기
import Home from "./components/Home"
import Chicken from "./components/Chicken"
import Duckgugong from "./components/Duckgugong"
  • 라우팅할 컴포넌트를 주소와 함께 적어준다.
  • name 속성을 사용하면 주소를 이동할 때, path 대신에 사용할 수 있지만 쓰지 않아도 상관없다!
    • path 대신 사용한다는 말은 주소는 path로 이동되지만 라우팅시 개발자가 넘기는 파라미터를 url 대신 name 속성을 이용할 수 있다는 의미!
  • 아래 나와있진 않지만 redirect 속성도 있는데 만약 path가 "/"이고 redirect 옵션으로 redirect: "/hi"가 있다면 "/"경로로 이동할 때 "/hi"경로로 리다이렉트된다
//3. 컴포넌트마다 route 설정하기
const routes = [
    { path: "/", name: "Home", component: Home },
    { path: "/duckgugong", name: "MyName", component: Duckgugong },
    { path: "/chicken", name: "FavoriteFood", component: Chicken }
]
 

다양한 히스토리 모드 | Vue Router

다양한 히스토리 모드 history 옵션을 사용하면 다른 히스토리 모드 중에서 선택할 수 있습니다. 해시 모드 해시 히스토리 모드는 createWebHashHistory() 를 이용해 만듭니다. import { createRouter, createWebHas

router.vuejs-korea.org

  • 모르면 검색하고 그냥 createWebHistory를 사용하자
// 4. createRouter로 router 만들기
const router = createRouter({
    history: createWebHistory(),
    routes: routes
})
  • 마지막으로 router를 프로젝트에 적용시키자!
// 5. use(router)로 프로젝트에 라우팅 적용하기
createApp(App).use(router).mount('#app')

main.js에 라우팅 설정하기 전체 소스코드

import { createApp } from 'vue'
// 1. createWebHistory, createRouter 불러오기
import { createWebHistory, createRouter } from 'vue-router'
import App from './App.vue'
// 2. 라우팅할 컴포넌트 불러오기
import Home from "./components/Home"
import Chicken from "./components/Chicken"
import Duckgugong from "./components/Duckgugong"

//3. 컴포넌트마다 route 설정하기
const routes = [
    { path: "/", name: "Home", component: Home },
    { path: "/duckgugong", name: "MyName", component: Duckgugong },
    { path: "/chicken", name: "FavoriteFood", component: Chicken }
]

// 4. createRouter로 router 만들기
const router = createRouter({
    history: createWebHistory(),
    routes: routes
})

// 5. use(router)로 프로젝트에 라우팅 적용하기
createApp(App).use(router).mount('#app')

 

3. App.vue에 적용하기 (렌더링+URL 변경)

  • 라우팅된 컴포넌트를 이동시키고 화면에 나타내보자!
  • <router-view/> (or <RouterView/>를 이용해서 라우팅한 컴포넌트들을 화면에 나타낼 수 있다
    • 예를 들어 현재 url이 "/duckgugong"이라면 <router-view/>는 <Duckgugong/> 컴포넌트가 된다
  • $router.push 키워드로 url을 변경할 수 있다. 또한 <router-link/>를 이용해 a 태그와 같은 역할을 하게 할 수 있다
<template>
  <!-- 라우팅된 컴포넌트: 현재 url이 "/"이라면 Home 컴포넌트가 여기에 들어올 것이다!-->
  <router-view />

  <!-- url 이동시키기! -->
  <!-- 이벤트와 $router.push를 이용해 url을 변경시킬 수 있다! -->
  <button @click="$router.push('/duckgugong')">Go to "Duckgugong"</button>
  <!-- router-link: a태그와 같은 역할! -->
  <router-link to="/chicken">Go to "Chicken</router-link>
  <button @click="goToHome">Go to Home</button>
</template>

<script>
export default {
  name: "App",
  methods: {
    goToHome() {
      // name 속성으로 url 이동하기
      this.$router.push({ name: "Home" });
    },
  },
};
</script>

 

  • 실행 화면은 아래와 같이 URL이 변경됨에 따라 다른 컴포넌트가 화면에 렌더링된다!


Dynamic Routing (URI, Query Parameter) 

  • Vue.js에서는 React와 다르게 별도의 hook 없이 uri parameter와 query parameter를 사용할 수 있다!
  • uri parameterquery parameter에 접근할 땐 아래와 같이 쉽게 접근할 수 있다
// uri parameter
$route.params.[uri parameter 이름]
// query parameter
$route.query.[query parameter 이름]

예시

main.js

  • 라우팅을 적용할 컴포넌트를 설정할 때, uri parameter 사용하면 path에 /경로명/uri parameter 이름으로 설정한다.
    • 컴포넌트에서 uri parmeter에 접근할 때 사용할 이름이다
  • query parameter를 사용할 때는 별도의 설정 없이 path를 설정해주자!
import { createApp } from 'vue'
import { createWebHistory, createRouter } from 'vue-router'
import App from './App.vue'
import Home from "./components/Home"
import User from "./components/User"
import Chicken from "./components/Chicken"

const routes = [
    { path: "/", name: "Home", component: Home },
    // URI parameter를 사용할 컴포넌트 
    { path: "/user/:user_id", component: User },
    // querty parameter를 사용할 컴포넌트
    { path: "/chicken", component: Chicken }
]

const router = createRouter({
    history: createWebHistory(),
    routes: routes
})

createApp(App).use(router).mount('#app')

App.vue

  • routing을 적용할 컴포넌트를 렌더링하기 위한 router-view를 설정해두고 모든 컴포넌트에서 Home 컴포넌트로 이동할 버튼을 생성해두자
<template>
  <router-view />
  <div><button @click="$router.push('/')">go Home!</button></div>
</template>

<script>
export default {
  name: "App",
};
</script>
<style scoped>
button {
  font-size: 24px;
  color: blue;
}
</style>

components/Home.vue

  • uri parameter를 사용하는 User 컴포넌트와 query parameter를 사용하는 Chicken 컴포넌트로 이동할 버튼을 추가하자!
<template>
  <h1>This is "Home" Component</h1>
  <button @click="$router.push('/user/1')">go to /user/1</button>
  <button @click="$router.push('/chicken?brand=bbq')">
    go to /chicken?brand=bbq
  </button>
</template>

<style scoped>
button {
  font-size: 24px;
}
</style>

components/user.vue (uri parameter)

  • input에 경로를 입력하고 enter 키를 누르면 "/user/user_id" 경로로 이동할 수 있는 기능을 구현!
    • 엔터를 누르면 브라우저의 url이 "/user/1234" 이런 식으로 변경될 것이다
<template>
  <h1>I'm "User" Component</h1>
  <h2>My user_id is {{ $route.params.user_id }}</h2>
  <span>user_id:</span><input @keyup.enter="changePath" />
</template>
<script>
export default {
  methods: {
    changePath(e) {
      this.$router.push(`/user/${e.target.value}`);
    },
  },
};
</script>

components/chicken.vue (query parameter)

  • input에 경로를 입력하고 enter 키를 누르면 "/chicken?brand=brand" 경로로 이동할 수 있는 기능을 구현!
    • 엔터를 누르면 브라우저의 url이 "/chicken?brand=bbq" 이런 식으로 변경될 것이다
<template>
  <h1>I'm "Chicken" Component</h1>
  <h3>My brand is {{ $route.query.brand }}</h3>
  <span>user_id:</span><input @keyup.enter="changePath" />
</template>
<script>
export default {
  methods: {
    changePath(e) {
      this.$router.push(`/chicken?brand=${e.target.value}`);
    },
  },
};
</script>

실행 화면

  • 각 path마다 현재 uri parameter와 query parameter가 화면에 나타나고 enter를 누를 때마다 input에 넣은 uri/query parameter로 잘 이동한다!


Prop 넘기기

  • 라우팅을 하면서 컴포넌트들에게 prop을 넘길 수 있다. 
  • 라우팅을 하는 모든 컴포넌트들이 공용으로 사용하는 prop을 넘길 수도 있고 라우팅을 하는 컴포넌트들이 개별적으로 사용하는 prop을 넘길 수도 있다.

공용으로 사용하는 prop으로 넘기기

  • RouterView(router-view)에 v-bind를 이용해서 prop을 넘기면 라우팅되는 컴포넌트들이 공용으로 사용할 수 있는 prop을 넘겨줄 수 있다.
<RouterView :sharedProp="`I'm shared prop`" />

URI 파라미터를 prop으로 넘기기

  • 라우팅을 설정할 때, props 옵션을 true로 설정하면 해당 컴포넌트는 URI 파라미터명으로 prop을 받을 수 있다.
  • 만약 아래와 같이 설정을하면 count라는 prop으로 받아서 쓸 수 있다.
{ path: "/prop-child1/:count", component: PropChild1, props: true },

정적인 데이터를 prop으로 넘기기

  • props 옵션에 object의 key, value 쌍으로 데이터를 넘겨주면 key로 prop을 받을 수 있다.
  • 만약 아래와 같이 설정을하면 name라는 prop으로 받아서 쓸 수 있다. (값은 "duck")
{ path: "/prop-child2", component: PropChild2, props: { name: "duck" } }

동적(데이터를 가공해서)인 데이터를 넘기기

  • 정적인 데이터 이왜에도 함수의 리턴 값을 이용해서 데이터를 연산하거나 uri나 query 파라미터에 관련된 값에 대해 연산을 한 후 prop으로 넘길 수 있다.
  • 만약, 함수의 파라미터가 route라고 하면 route.query.[파라미터명]으로 query 파라미터에 접근할 수 있고 route.params.[파라미터명]으로 uri 파라미터에 접근할 수 있다.
  • 아래처럼 라우팅 설정을 하고 url이 /prop-child3?brand="kyochon"이라면 컴포넌트에서 "kyochon is good"이라는 값을 가지고 이름이 chicken인 prop을 사용할 수 있다!
{ path: "/prop-child3", component: PropChild3, props: route => ({ chicken: `${route.query.brand} is good` }) }

Example

  • 위에 나온 네가지 방법으로 간단한 소스코드를 작성해봤다!
  • 라우팅된 컴포넌트들이 각각 받는 prop을 화면에 출력해보자!

main.js

  • routing 설정!
import { createApp } from 'vue'
import { createWebHistory, createRouter } from 'vue-router'
import App from './App.vue'
import Home from "./components/Home"
import PropChild1 from "./components/PropChild1"
import PropChild2 from "./components/PropChild2"
import PropChild3 from "./components/PropChild3"


const routes = [
    { path: "/", component: Home },
    { path: "/prop-child1/:count", component: PropChild1, props: true },
    { path: "/prop-child2", component: PropChild2, props: { name: "duck" } },
    { path: "/prop-child3", component: PropChild3, props: route => ({ chicken: `${route.query.brand} is good` }) },

]

const router = createRouter({
    history: createWebHistory(),
    routes: routes
})

createApp(App).use(router).mount('#app')

App.vue

  • RouterView에 라우팅된 컴포넌트들이 공용으로 사용할 sharedProp이라는 prop을 넘겨준다!
<template>
  <RouterView :sharedProp="`I'm shared prop`" />
  <div><button @click="$router.push('/')">go Home!</button></div>
</template>

<script>
export default {
  name: "App",
};
</script>
<style scoped>
button {
  font-size: 24px;
  color: blue;
}
</style>

component/PropChild1.vue

  • 공통으로 받는 sharedProp과 uri 파라미터를 count라는 prop으로 받고 있다!
<template>
  <h2>I'm PropChild1</h2>
  <h3>My prop is: {{ count }}</h3>
  <h4>Shared Prop is: {{ sharedProp }}</h4>
</template>

<script>
export default {
  props: ["sharedProp", "count"],
};
</script>

component/PropChild2.vue

  • 공통으로 받는 sharedProp과 정적인 name이라는 prop을 받고 있다!
<template>
  <h2>I'm PropChild2</h2>
  <h3>My prop is: {{ name }}</h3>
  <h4>Shared Prop is: {{ sharedProp }}</h4>
</template>

<script>
export default {
  props: ["sharedProp", "name"],
};
</script>

component/PropChild3.vue

  • 공통으로 받는 sharedProp과 query 파라미터를 가공한 chicken이라는 prop을 받고 있다!
<template>
  <h2>I'm PropChild3</h2>
  <h3>My prop is: {{ chicken }}</h3>
  <h4>Shared Prop is: {{ sharedProp }}</h4>
</template>

<script>
export default {
  props: ["sharedProp", "chicken"],
};
</script>
  • 각 routing