Vue 3.0/05.vuerouter

[vue3-router] 06. route meta field와 multiple layout

  • -

이번 포스트에서는 route의 meta field를 활용한 dynamic layout에 대해 살펴보자.

 

기존의 layout

 

named view를 이용한 layout 구성

앞서 우리는 named view를 이용해 페이지의 layout을 구성한 바 있다.

{
  path:"/named/home",
  components:{
    header: HeaderView,
    footer: FooterView,
    default:SiteMainView,
  }
},

 

또는 Header와 Footer는 고정하고 SiteMainView만 RouterView의 형태로 작성해 볼 수도 있다. 하지만 이때의 문제는 각 뷰 마다 layout이 "고정적"이라는 데 있다. 

 

어떻게 하면 필요에 따라 여러가지 레이아웃을 구성해 볼 수 있을까?

 

 

multiple layout

 

Layout View

다음과 같이 2개의 layout view가 있고 필요에 따라 View Component에서 특정 layout을 사용하도록 구성한다고 생각해보자. 핵심은 layout view에서는 slot을 통해 표시할 DOM을 공급받는다는 점이다.

<!-- LayoutSimple.vue -->
<template>
    <div>
        <slot></slot>
    </div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

<!-- LayoutHeaderFooter.vue -->
<template>
    <div>
        <CommonHeader></CommonHeader>
        <slot></slot>
        <CommonFooter></CommonFooter>
    </div>
</template>

<script setup>
import CommonHeader from "@/components/layout/CommonHeader.vue"
import CommonFooter from '@/components/layout/CommonFooter.vue';
</script>

<style lang="scss" scoped></style>

 

 

dynamic component와 slot

multiple layout의 기본 컨셉을 dynamic component와 slot을 이용한다. 만약 다음과 같이 component를 구성하게 된다면 어떨까?

대상 컴포넌트를 router-view로 보여주는데 이는 대상 layout 에 slot으로 공급된다.

 

Header와 Footer 사이에 main content가 들어갈 영역<component :is>를 이용해서 동적으로 component가 교체될 예정인데 이 컴포넌트들은 사실 layout 들이다. 각각의 layout들은 slot을 가지고 있어서 <component :is>가 전달해준 내용을 slot에 출력하는데 이 내용은 router-view이다. 따라서 router-link에서 선택한 이동 대상 즉 진짜 content가 최종적으로는 LayoutView의 slot 영역에 출력되게 된다.

 

그럼 어떻게 router-link의 대상 컴포넌트에 적합한 layout을 넘겨줄 것인가?

 

router와 meta field

route를 작성할 때 사용하는 meta field는 사용자 정의의 여러 속성을 전달 할 수 있는데 여기에 필요한 Layout의 이름을 전달할 수 있다.

import { createRouter, createWebHistory } from 'vue-router'
// layouts
import LayoutSimple from '@/components/layout/LayoutSimple.vue'
import LayoutHF from '@/components/layout/LayoutHeaderFooter.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('@/views/HomeView.vue'),
      meta: { layout: LayoutSimple } //어떻게 표현할 것인가 정보를 meta로 전달
    },
    {
      path: '/main',
      component: () => import('@/views/MainView.vue'),
      meta: { layout: LayoutHF } //어떻게 표현할 것인가 정보를 meta로 전달
    }
  ]
})

export default router

 

dynamic component에서 meta field 사용

마지막으로 dynamic component에서 router의 meta field를 사용하는 모습을 살펴보자.

<template>
  <router-link to="/">Home</router-link> | <router-link to="/main">Main</router-link>

  <h1>동적 레이아웃 컴포넌트와 함께 사용</h1>
  <component :is=" route.meta.layout || 'div'">
    <!--layout component의 slot으로 router-view 전달-->
    <router-view></router-view>
  </component>
  <hr>
  <h1>동적 레이아웃 컴포넌트 없이 사용</h1>
  <router-view></router-view>
</template>

<script setup>
import { useRoute } from "vue-router"
const route = useRoute();
</script>

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.