Vue.jsでSPA(シングルページアプリケーション)を構築していると、ページごとに異なるレイアウトを適用したいケースがあります。例えば、ログインページはヘッダーやサイドバーを表示せずにシンプルなデザインにしたい、管理画面は専用のレイアウトに切り替えたいなどです。
本記事では、Vue Routerとコンポーネント構成を活用して、ページごとにレイアウトを切り替える実装方法を解説します。Nuxt.jsにおけるlayout機能にも通じる考え方のため、両方の開発に応用できます。
ルーティングごとにレイアウトを分岐する基本構成
Vue Routerでは、ルート定義にメタ情報を付けることができます。ここにレイアウト名を定義し、App.vue(またはルートの親コンポーネント)でそれをもとに表示レイアウトを動的に切り替えます。
router/index.js
const routes = [
{
path: '/login',
name: 'Login',
component: () => import('@/pages/Login.vue'),
meta: { layout: 'empty' }
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/pages/Dashboard.vue'),
meta: { layout: 'admin' }
},
{
path: '/',
name: 'Home',
component: () => import('@/pages/Home.vue'),
meta: { layout: 'default' }
}
];
App.vueでレイアウトを動的に切り替える
App.vueのtemplate内で、ルート情報に基づき表示するレイアウトコンポーネントを変更します。
<template>
<component :is="layout">
<router-view />
</component>
</template>
<script>
import DefaultLayout from '@/layouts/DefaultLayout.vue';
import AdminLayout from '@/layouts/AdminLayout.vue';
import EmptyLayout from '@/layouts/EmptyLayout.vue';
export default {
computed: {
layout() {
const layoutName = this.$route.meta.layout || 'default';
return {
default: DefaultLayout,
admin: AdminLayout,
empty: EmptyLayout
}[layoutName];
}
}
};
</script>
このようにすることで、ルーティングに応じて動的にレイアウトを切り替えることが可能になります。
レイアウトコンポーネントの例
各レイアウトは単なる親コンポーネントで、共通部分(ヘッダーやサイドバーなど)を持ちつつ、<slot>
で子コンテンツを展開します。
layouts/AdminLayout.vue
<template>
<div class="admin-layout">
<AdminHeader />
<div class="main">
<AdminSidebar />
<div class="content">
<slot />
</div>
</div>
</div>
</template>
Nuxt.jsでの応用
Nuxt.jsではlayouts/
ディレクトリにレイアウトを定義し、各ページファイルのlayout
プロパティで切り替えるだけで同様の実装が可能です。
// pages/login.vue
export default {
layout: 'empty'
}
Vue Routerを手動で使っているVue CLI環境でも、Nuxtのような柔軟なレイアウト切り替えが実現できるので、大規模アプリの設計にも有効です。
まとめ
Vue.jsでは、ルートごとにレイアウトを切り替えることで、ページの性質に応じた柔軟なUI設計が可能になります。特に管理画面・ログインページ・ユーザー向けページなどが混在するシステムでは、この手法が非常に役立ちます。Nuxt.jsでも同様の考え方が使われているため、フレームワークを跨いでも通用する実装スタイルです。