본문 바로가기
Study

[Vue.js] Vue Router (Nested Router vs Named Views)

by 안자두 2023. 5. 27.

Router

Vue에서는 Vue Router라는 라이브러리를 사용하여 SPA(Single Page Application)을 구현한다.

라이브러리는 npm을 통해 설치할 수도 있고, 아래 예시처럼 CDN으로 가져올 수도 있다.

const router = new VueRouter({   
  routes: [
    {
      path: '경로명',
      component: {
      	template: '<div></div>'
      }
    }
  ] 
});

new Vue({
  el: '#app',
  router: router,
});

vue-router로부터 VueRouter를 가져와 새 라우터를 정의해 준다.
VueRouter안에는 routes라는 속성의 값으로 route들을 객체 형식으로 배열에 정의할 수 있다.

정의한 VueRouter는 Vue 인스턴스에 router라는 속성 값으로 할당시킨다.
이렇게 되면 이 Router는 해당 Vue 인스턴스에 종속되어 이 Vue 앱이 포함되는 위치에서만 사용할 수 있다.

 

<body>
  <div id="app">
    <div>
      <router-link to="/login">Login</router-link>
      <router-link to="/main">Main</router-link>
    </div>
    <section>
      <router-view></router-view>
    </section>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
  <script>
    const LoginComponent = {
      template: '<div>login</div>'
    }
    const MainComponent = {
      template: '<div>main</div>'
    }

    const router = new VueRouter({
      routes: [
        {
          path: '/login',
          component: LoginComponent
        },
        {
          path: '/main',
          component: MainComponent
        }
      ] 
    });
    
    new Vue({
      el: '#app',
      router: router,
    });
  </script>
</body>

경로를 이동하기 전

<router-link>는 a태그와 같은 역할을 한다. 현재 페이지에서 다른 페이지로 이동할 수 있도록 링크를 걸어준다.
라우팅 된 페이지가 뜨는 부분은 <router-view>이다.

<router-view>에는 new VueRouter()로 설정해 준 route의 컴포넌트가 들어가게 된다.

만약 위의 예제에서 Login을 클릭하면 /login으로 이동하게 되고 아래와 같이 변경된다.

login으로 이동한 후

section 태그 안의 router-view 자리에 login으로 정의해 둔 컴포넌트가 들어간 것을 확인할 수 있다.

페이지로 설정할 컴포넌트를 VueRouter에 경로와 컴포넌트를 객체로 추가해 주면 된다.

 

Nested Router

routes에 children 속성을 추가하여 중첩 라우터를 손쉽게 구현할 수도 있다.

위의 예제에서 아래 부분만 조금 수정하여 확인해 보았다.

const LoginComponent = {
  template: '<router-view></router-view>'
}

const LoginMainComponent = {
  template: '<h1>login - main</h1>'
}

const LoginSubComponent = {
  template: '<div>login - sub</div>'
}

const MainComponent = {
  template: '<div>main</div>'
}

const router = new VueRouter({
  routes: [
    {
      path: '/login',
      component: LoginComponent,
      children: [
        {
          path: '/',
          component: LoginMainComponent
        },
        {
          path: 'sub',
          component: LoginSubComponent
        },
      ]
    },
    {
      path: '/main',
      component: MainComponent
    }
  ] 
});

이런 식으로 추가를 해주면 /login로 진입했을 때,

/login

이렇게 path를 루트로 설정한 LoginMainComponent까지 뜨게 되고, /login/sub로 이동하게 되면 아래와 같이 뜨게 된다.

/login/sub

 

Named Views

또한, 특정 URL에 여러 개의 컴포넌트를 영역 별로 지정하여 렌더링 할 수도 있다.

<div id="app">
    <div>
      <router-link to="/login">Login</router-link>
      <router-link to="/main">Main</router-link>
    </div>
    <section>
      <router-view></router-view>
      <router-view name="main"></router-view>
      <router-view name="sub"></router-view>
    </section>
  </div>

body를 조금 수정해 주었다.
router-view에 name을 지정해 주면, 해당하는 이름을 가진 component만 들어가게 된다.

const router = new VueRouter({
  routes: [
    {
      path: '/login',
      components: {
        default: LoginComponent,
        main: LoginMainComponent,
        sub: LoginSubComponent,
      }
    },
    {
      path: '/main',
      component: MainComponent
    }
  ] 
});

VueRouter는 이렇게 수정하면 된다.
주의해야 할 점은, component가 여러 개이기 때문에 components로 복수형으로 작성해 주어야 한다는 점이다.
객체의 key 값이 router-view의 name이 되고, value에 해당하는 component가 그 위치에 할당된다. default는 name을 설정해주지 않은 부분에 할당된다.

그러면 아래처럼 동시에 여러 컴포넌트를 표시할 수 있게 된다.

/login

 

Nested Router vs Named Views

Nested Router는 한 페이지 내에서 세부 경로를 통해 일부분에 대해서만 변경할 경우 사용한다. 예를 들어, 페이지 내용은 동일하지만 탭을 이용해서 선택한 탭의 내용만 보여주는 경우가 여기에 해당한다.
Named Views는 한 페이지 내에서 여러 개의 컴포넌트를 영역 별로 지정하여 렌더링 할 때 사용한다. 페이지가 다르지만 공통으로 사용해야 할 컴포넌트가 있으면 name으로 이 부분을 지정해 주면 해당 페이지의 내용은 변경되면서 공통부분은 동일하게 보여줄 수 있다.


 

REF

https://joshua1988.github.io/web-development/vuejs/vuejs-tutorial-for-beginner/

https://router.vuejs.org/guide/

https://v2.ko.vuejs.org/v2/guide/routing.html

728x90