Vue.js Router
뷰 라우터

 

 

리액트를 저버리고 Vue.js를 공부해야 합니다. 이유는 간단하죠. 일 때문입니다. 새로운 프레임워크를 배워야 하기 때문에 기대가 되는데요.

 

이전에 Composition API 이전의 방식을 잠깐 맛만 봤었습니다. 이제 기억속에서 주섬주섬 꺼내 복습을 해보고, Composition API 방식을 새롭게 배울 겁니다.

 

오늘 학습한 내용인 뷰에서 라우팅 처리를 하는 방법에 대해 알아보겠습니다.

 

 

1. vue-router 설치


> npm i vue-router

 

다른 글에서는 라우터를 설치하면 src 폴더에 router 폴더가 생긴다는데, 저는 안 생겨서 하나 만들었습니다.

 

 

2. ./src/router/index.js


import { createRouter, createWebHistory } from "vue-router";
import Home from '../pages/HomeComp'
import About from '../pages/AboutComp'
import Contact from '../pages/ContactComp'
import Portfolio from '../pages/PortfolioComp'
import Error from '../pages/ErrorComp'

const routes = [
    { path : '/', name : 'Home', component : Home },
    { path : '/about', name : 'About', component : About },
    { path : '/portfolio', name : 'Portfolio', component : Portfolio },
    { path : '/contact', name : 'Contact', component : Contact },
    { path : '/404', name : 'Not-Found', component : Error },
    { path: '/:pathMatch(.*)*', redirect : '/404' }
]

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

export default router;

 

대략 포트폴리오 느낌으로 메뉴를 구성했고 원하는 페이지들로 구성해서 routes 객체 배열을 만들어줍니다. routes에는 각 path별로 name과 component를 할당해줍니다. 각 컴포넌트들도 만들어줘야 합니다.

 

페이지들마다 메인 컨텐츠들이 다를 테니 제 경우에는./src/pages 폴더를 만들어 한 곳으로 모아줬습니다.

 

마지막 경로에는 에러 페이지를 보여주기 위한 '/404'  페이지로 리다이렉션 시켜주며, /404 경로에 Error 컴포넌트를 할당해 주었습니다.

 

리액트 라우터 v6 에서는 간편하게 '*' 문자열로 에러 페이지를 잡아줬는데 말이죠.. 

 

이렇게 라우터를 만들어 줬으니 main.js에서 라우터를 불러와 연결시켜줘야 합니다.

 

 

3. ./src/main.js


import { createApp } from 'vue'
import App from './App.vue'
import router from './router'  //<- 라우터 불러오기

createApp(App).use(router).mount('#app') //<- 라우터 사용하기

 

여기까지 작성을 완료했다면, 라우터를 사용할 준비가 끝났습니다. 이제 라우팅을 처리해주는 곳으로 이동해서 <router-link/>와 <router-view/>를 사용해 라우팅 처리를 해보겠습니다.

 

 

4. 레이아웃 구성


<App>
    <HeaderComp/>
    <MainComp/>
    <FooterComp/>
</App>

 

기본적인 레이아웃 방식으로 Header 컴포넌트에 네비게이션 메뉴를 배치하고 메뉴에 따라 Main 컴포넌트의 내용이 변경되도록 레이아웃을 구성했습니다.

 

레이아웃 구성은 달라질 수 있으므로 참고 바랍니다. 그렇다면 제 레이아웃 방식으로는 HeaderComp.vue와 MainComp.vue 코드만 확인하면 되겠습니다.

 

 

5. HeaderComp.vue


<template>
    <header class="header">
        
        <div class="logo">
            <h1>
                <router-link to='/'>꾸생</router-link>
            </h1>
        </div>
        
        <nav class="nav">
            <ul class="nav-list">
                <li>
                    <router-link to='/'>Home</router-link>
                </li>
                <li>
                    <router-link to='/about'>About</router-link>
                </li>
                <li>
                    <router-link to='/portfolio'>Portfolio</router-link>
                </li>
                <li>
                    <router-link to='/contact'>Contact</router-link>
                </li>
            </ul>
        </nav>
        
    </header>
</template>

 

Header 컴포넌트에서 네이게이션 메뉴를 만들어 줬습니다, <li/> 안 <router-link/> 태그를 사용해 해당 경로의 컴포넌트로 이동시켜줄 수 있습니다. to 속성에 경로를 작성해줍니다.

 

 

6. MainComp.vue


<template>
    
    <main class="main">
        <router-view />
    </main>

</template>

 

Main 컴포넌트는 경로마다 내용이 바뀌는 부분으로 <router-view/>만 붙여주면 스타일 작업 이외에 건드릴 필요가 없어 보입니다.

 

이제 스타일을 입히고 해당 컴포넌트 페이지들이 잘 나오나 확인해보겠습니다.

 

 

7. 결과


 

vue.js 3.0 router
뷰 라우터

 

 

8. Params 사용하기(기존 방식)


...
import ParamsComp from '../pages/ParamsComp' <-- 추가

const routes = [
    { path : '/', name : 'Home', component : Home },
    { path : '/about', name : 'About', component : About },
    { path : '/portfolio', name : 'Portfolio', component : Portfolio },
    { path : '/contact', name : 'Contact', component : Contact },
    { path : '/params/:id', component : ParamsComp },  <-- 추가
    { path : '/404', name : 'Not-Found', component : Error },
    { path : '/:pathMatch(.*)*', redirect : '/404' }
]

 

./router/index.js 파일에 routes 배열에 params를 사용할 컴포넌트를 추가해주었습니다. 

 

./src/pages/ParamsComp.vue 

<template >
    <div>
        Here : {{this.$route.params.id}}
    </div>
</template>
<script>
export default {
    name : 'ParamsComp',
    beforeCreate(){
        console.log(this.$route.params.id);
    },
}
</script>
<style>
    
</style>

 

ParamsComp 컴포넌트에서 url에서 params를 가져오려면 this.$route.params.id를 사용합니다. 인스턴스가 초기화된 후 params.id를 찍어보겠습니다. route 배열에 추가한 데로 '/params/어쩌고저쩌고' 형식으로 접속해줍니다

 

Vue.js 뷰 라우터 Params
뷰 라우터 Params

 

console.log에서도 잘 찍히는 걸 확인할 수 있습니다. 이제 params를 사용할 수 있게 되었습니다. 👏

params를 사용해봤으니 이제 Query 방식을 알아보겠습니다.

 

Params는 URL을 '/' 문자열로 구분해 값을 가져오는 반면 쿼리 스트링 방식은 규칙이 조금 추가되었습니다. 전에 쿼리 스트링에 관한 글을 포스팅했었는데요. 아래 글을 참고 바랍니다.

 

 

 

URL 쿼리 스트링(Query String)

쿼리 스트링(Query String) 쿼리 스트링이란, 사용자가 입력한 데이터를 전달하는 방법 중 하나로 미리 정해진 규칙으로 URL주소에 담아 넘겨주는 방식이다. 쿼리 스트링의 3가지 규칙만 알고 있으

juni-official.tistory.com

 

9. Query 사용하기


import QueryComp from '../pages/QueryComp'

const routes = [
    { path : '/', name : 'Home', component : Home },
    { path : '/about', name : 'About', component : About },
    { path : '/portfolio', name : 'Portfolio', component : Portfolio },
    { path : '/contact', name : 'Contact', component : Contact },
    { path : '/params/:id', name : 'Params',  component : ParamsComp },
    { path : '/query', name : 'Query',  component : QueryComp },
    { path : '/404', name : 'Not-Found', component : Error },
    { path : '/:pathMatch(.*)*', redirect : '/404' }
]

 

 

Params와 같이 ./src/route/index.js 파일에 다시 QueryComp 컴포넌트를 불러와 routes 배열에도 추가해주겠습니다.

 

./src/pages/QueryComp.vue

<template >
    <div>
        Query : {{this.$route.query.id}}
    </div>
</template>
<script>
export default {
    name : 'QueryComp',
    mounted(){
        console.log(this.$route.query);
    }
}
</script>
<style lang="">
    
</style>

 

QueryComp 컴포넌트도 마찬가지로 Params와 같이 $route.query를 사용해 값을 가져옵니다.

 

Vue.js 뷰 라우터 QueryString
뷰 라우터 Query

 

 

10. Composition API에서 Params, Query


import { useRoute, useRouter } from 'vue-router'

export default {
    name : 'RouterComp',
    setup(){
        const router = useRouter();
        const { params, query } = useRoute();
        const param = ref(params.id);
        const queryName = ref(query.name);
        
        return { 
            router,
            param,
            queryName,
        }
    }
}

 

리액트의 경험이 있으시다면 Compsition API에서 쉽게 사용할 수 있습니다.

 

쿼리 스트링 형식으로 url에 접속했을 때, 해당 값들이 잘 가져와지는 것을 확인할 수 있습니다. 끝.

 

마지막 팁으로 <route-link/> 태그를 사용하지 않고 단순히 버튼 태그로 페이지를 이동하고 싶을 경우 아래처럼 사용합니다.

 

 

편한 방식

<button @click="$router.push('/query?id=this_is_query')">
	Go
</button>

기존 방식

$router.push({name: 'Page', params: { key: '10' }});

 

원래 기존 방식으로 사용해야 페이지 이동과 갱신이 이루어집니다. 편한 방식을 사용하면 url은 이동하지만 페이지 갱신이 안되기 때문에 <router-view/> 컴포넌트에 key값을 넣어주면 페이지 갱신까지 됩니다.

 

<router-view :key="$route.fullPath" />

 

 

참고


 

Do we have router.reload in vue-router?

I see in this pull request: Add a router.reload() Reload with current path and call data hook again But when I try issuing the following command from a Vue component: this.$router.reload() I get...

stackoverflow.com