기본 콘텐츠로 건너뛰기

vue3 레이아웃 구분 설정하기 ( LoginLayout, DefaultLayout, PreviewLayout.. ) - vuejs

레이아웃 설정 시, 로그인 구조, 기본 구조, 특수 구조 등 다르게 설정하기


App.vue

<template>
  <RouterView />
</template>

<script setup>
import { RouterView } from 'vue-router'
</script>

LoginLayout.vue (로그인용 화면 구조)

<template>
  <RouterView />
</template>

<script setup>
import { RouterView } from 'vue-router';
</script>

<style lang="scss">
@import "@/assets/scss/login.scss";
</style>

DefaultLayout.vue (기본 화면 구조)

<template>
  <Header :menuno="info.menuNo" :subno="info.subNo" />
   <RouterView />
</template>

<script setup>
import { RouterView } from 'vue-router';
import { infoStore } from "@/stores/info";

import Header from "@/components/Header.vue";

const info = infoStore().info;// info.menuNo : 메뉴 위치,   info.subNo : 서브 메뉴 위치
</script>

<style lang="scss">
@import "@/assets/scss/style.scss";
</style>

PreviewLayout.vue (미리보기 화면 구조)

<template>
  <div class="wrap m_flex">
      <LeftInfo :title="title" />
      <RouterView />
  </div>
</template>

<script setup>
import { RouterView } from 'vue-router';
import LeftInfo from "@/components/LeftInfo.vue";

const title = document.title.replace("... - ", "");
</script>

<style lang="scss">
@import "@/assets/scss/preview.scss";
</style>


main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

import "@/assets/css/common.css"

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')

info.js (스토어용)

import { ref } from "vue";
import { defineStore } from "pinia";

export const infoStore = defineStore("info", () => {
  // 현재 화면 위치 확인(메뉴 위치 확인)
  const info = ref({
    menuNo: 0,// 메인 메뉴
    subNo: null,// 서브 메뉴
  })

  return { info: info.value }
})

src/router/index.js (라우터에서 레이아웃 설정)

import { createRouter, createWebHistory } from 'vue-router'
import { authStore } from '@/stores/auth';

const title = "공통으로 보여지는 브라우저 타이틀 - ";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    { path: "/", redirect: "/main" },
    { 
      path: "/404", name: "notFound", 
      component: () => import("@/components/layout/ErrorLayout.vue") 
    },
    { path: "/:pathMatch(.*)*", redirect: "/404"},

    // 로그인 레이아웃
    {
      path: "/login",
      name: "loginlayout",
      component: () => import("@/components/layout/LoginLayout.vue"),
      children: [
        {
          path: "",
          name: "login",
          component: () => import("@/views/Login.vue"),
          meta: {
            title: title + " - Login"
          }
        }
      ]
    },

    // 미리보기 레이아웃
    {
      path: "/preview",
      name: previewlayout",
         component: () => import("@/components/layout/PreviewLayout.vue"),
         // meta: {
         //   requiresAuth: true,
         // },
         children:[
           {
              path: "view1",
              name: "view1",
              component: () => import("@/views/preview/View1.vue"),
              meta: {
                 title: title + " - 미리보기 1"
              }
           },
           {
              path: "view2",
              name: "view2",
              component: () => import("@/views/preview/View2.vue"),
              meta: {
                 title: title + " - 미리보기 2"
              }
           }
        ]
    },

    // 기본 레이아웃
    {
      path: "/",
      name: "defaultLayout",
      component: () => import("@/components/layout/DefaultLayout.vue"),
      meta: {
        requiresAuth: true,
      },
      children: [
         {
           path: "main",
           name: "main",
           component: () => import("@/views/Main.vue"),
           meta: {
             title: title + " - OOO 메인"
           }
         },
         {
           path: "sub",
           name: "sub",
           component: () => import("@/views/content/Sub.vue"),
           meta: {
             title: title + " - OOO 서브"
           }
         },
         // ......
       ]
    },
  ]
});

router.beforeEach((to, from) => {
  document.title = to.meta.title;
  
  const auth = authStore();

  if (to.meta.requiresAuth && !auth.auth.isLogin) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    return {
      path: '/login',
      // save the location we were at to come back later
      query: { redirect: to.fullPath },
    }
  }
});

export default router

로그인 화면, 기본 화면, 미리보기나 윈도우 팝업 같은 화면 등 여러 레이아웃이 필요할 때 위와 같이 -Layout.vue를 필요한 만큼 만들어서 라우터에서 연결해서 사용하면 된다


끝.