프로그래밍/Vue.js

vue3 > Layout 에 대해서 (기본 레이아웃 변경하기 > slot 사용하기)

에그티비 2024. 11. 22. 05:17

기본 레이 아웃은 여러개의 slot 을 사용할 수 없다.

 

[시나리오1]

기본 Layout > MainLayout.vue 으로 사용한다.

 

app.js 파일 내용

import './bootstrap';

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import MainLayout from './Layouts/MainLayout.vue'

createInertiaApp({
  resolve: name => {
    const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
    const page = pages[`./Pages/${name}.vue`]
    
    page.default.layout = page.default.layout || MainLayout

    return page
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

 

About.vue 

<template>
    <Head>
        <title>About</title>
    </Head>

    <div class="text-3xl font-bold">
        ABOUT
    </div>
</template>

<script setup>
import { Head, Link } from "@inertiajs/vue3";
</script>

 

위 파일에서는 <MainLayout></MainLayout> 으로 감싸지 않아도 기본으로 Layout 이 적용된다.

 

[시나리오2]

다른 Layout 으로 변경하고 싶다면 ?

 

새로운 Guest.vue 레이 아웃을 만든다.

// Guest.vue Layout

<template>
      <!-- Page Content -->
      <main class="py-10">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <slot />
        </div>
      </main>
    </div>
</template>

 

적용한다.

// Home.vue

<template>
      Guest
</template>

<script setup>
import Guest from '../Layouts/Guest.vue';

defineOptions({
  layout: Guest
})
</script>

 

[시나리오3]

여러개의 slot 을 사용한다면 ?

 

위의 방법으로는 에러가 발생하고, <Guest></Guest> 태그를 사용해서 감싸야 한다.

 

하지만, defineOptions 으로 Layout 를 이미 정해두었기 때문에..2번씩 Layout 이 적용되는 원치 않는 결과가 발생한다.

이때는 <Defaultlayout></Defaultlayout> 을 만들고 <Guest></Guest> 태그로 감싸는 방법으로 해결해야 한다.

 

// Defaultlayout.vue

<template>

      <!-- Page Heading -->
      <header v-if="title" class="bg-white shadow">
        <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
          {{ title }}
        </div>
      </header>

    <slot />
</template>

<script setup>

// Props 정의
const props = defineProps({
  title: {
    type: String,
    required: false
  }
})

</script>

 

// Guest.vue

<template>

     <slot name="header" />
  
      <!-- Page Content -->
      <main class="py-10">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <slot />
        </div>
      </main>
      
</template>

 

// Home.vue

<template>
  <guest>
  
    <template #header>
      asdf
    </template>

    <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
      Guest
    </div>
    
  </guest>
</template>

<script setup>
import Default from '../Layouts/Default.vue'
import Guest from '../Layouts/Guest.vue';

defineOptions({
  layout: (h, page) => h(Default, {
    title: '대시보드',
  }, () => page)
})

</script>

 

이렇게 하면, 기본 Layout 도 변경 하면서 여러개의 slot 도 사용 가능 하다.