画面によってレイアウトを切り替える

ログイン画面はヘッダー、フッターを表示。それ以外の画面ではヘッダー、サイドメニュー、フッターを表示といった形で画面ごとにレイアウトを切り替えたい。 Nuxtだとlayout プロパティを使って切り替えれるみたいだけどVue.jsではそのような仕組みがないようなのでSlotを使って代替した。

src/layouts/DefaultLayout.vue

<template lang="pug">
el-container
  el-header
  el-main
    slot
  el-footer 
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "DefaultLayout",
});
</script>
<style lang="scss" scoped>
@import "@/assets/styles/default.scss";
</style>

src/layouts/MenuLayout.vue

<template lang="pug">
el-container
  el-header
    p Jack
  el-container
    el-aside
      el-menu(:default-openeds="['1']")
        el-submenu(index="1")
          template(#title)
            i.el-icon-menu One
          el-menu-item-group
            el-menu-item(index="1-1" @click="moveTo('/')") Home
        el-submenu(index="2")
          template(#title)
            i.el-icon-user Two
          el-menu-item-group
            el-menu-item(index="2-1" @click="moveTo('/login')") Login
    el-main
      slot
  el-footer
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { useRouter } from "vue-router";

export default defineComponent({
  name: "MenuLayout",
  setup(props, context) {
    const router = useRouter();
    const moveTo = (path: string) => {
      router.push(path);
    };
    return {
      moveTo,
    };
  },
});
</script>
<style lang="scss" scoped>
@import "@/assets/styles/default.scss";
</style>

src/assets/styles/default.scss

.el-header {
  background-color: darkgray;
  text-align: right;
}
.el-aside .el-menu {
  background-color: rgb(165, 210, 231);
}
.el-footer {
  background-color: darkgray;
  position: relative;
  bottom: 0;
  width: 100%;
}

src/views/Login.Pagevue

<template lang="pug">
DefaultLayout
  el-row
    el-col(:span="10", :offset="7")
      el-form
        el-form-item(label="ID")
          el-input(placeholder="E-Mail", name="email")
        el-form-item(label="Password")
          el-input(placeholder="Password", name="password")
        el-button(type="primary", @click="login") login
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { useRouter } from "vue-router";
import DefaultLayout from "@/layouts/DefaultLayout.vue";

export default defineComponent({
  name: "LoginPage",
  components: {
    DefaultLayout,
  },
  setup(props, context) {
    const router = useRouter();
    const moveTo = (path: string) => {
      router.push(path);
    };
    return {
      moveTo,
    };
  },
  methods: {
    login(): void {
      console.log("#################");
      this.moveTo("/");
    },
  },
});
</script>

src/views/HomePage.vue

<template lang="pug">
MenuLayout
  p Hello
</template>

<script lang="ts">
import { defineComponent } from "vue";
import MenuLayout from "@/layouts/MenuLayout.vue";

export default defineComponent({
  name: "HomePage",
  components: {
    MenuLayout,
  },
});
</script>