Skip to main content

Command Palette

Search for a command to run...

How To Make Multi-layout Vue 3 application

Published
4 min read
How To Make Multi-layout Vue 3 application
E

Ethan Patrick is an experienced technology and software content writer with a proven track record of crafting high-quality content for various industries. With a strong understanding of software development, IT, and emerging technologies, John creates informative articles, blog posts, and technical guides that educate and inspire readers.

Building complex web applications often means managing distinct visual structures. An admin dashboard usually looks very different from a public marketing homepage or a user profile settings page. Manually switching CSS classes or using deeply nested v-if directives within your main application component quickly becomes messy and unmaintainable.

A better approach is implementing a multi-layout system in Vue 3, allowing you to seamlessly swap entire layout components based on the current route. This guide will walk you through setting up a clean, scalable, and reusable layout system for your Vue 3 application.

The Goal: Smart Layouts for VueJS

We want a system where defining the layout for a given view is as simple as adding a meta field to our route definition:

javascript

// Desired route definition
{
  path: '/admin',
  component: AdminDashboard,
  meta: {
    layout: 'AdminLayout' // <-- Define the layout here
  }
}

This approach provides smart layouts for VueJS applications, keeping our routing concise and our components clean.

Prerequisites

This guide assumes you are using Vue 3 with the Composition API (<script setup>), Vue Router, and Vite for your project structure.

Step 1: Define the Layout Components

First, create a dedicated directory for your layout components. Keep these simple—they just define the structure (headers, footers, sidebars) and a place where the main page content will be injected.

src/layouts/
├── DefaultLayout.vue
└── AdminLayout.vue

DefaultLayout.vue (e.g., for public pages)

<!-- src/layouts/DefaultLayout.vue -->
<template>
  <header>Public Website Header</header>
  <main class="default-content">
    <!-- This is where the page view goes -->
    <slot />
  </main>
  <footer>Copyright 2024</footer>
</template>

AdminLayout.vue (e.g., for secure areas)

<!-- src/layouts/AdminLayout.vue -->
<template>
  <div class="admin-wrapper">
    <aside>Admin Sidebar Navigation</aside>
    <main class="admin-content">
      <!-- This is where the page view goes -->
      <slot />
    </main>
  </div>
</template>

Step 2: The Layout Loader Component

The magic happens in a central component that acts as a dynamic wrapper around the currently displayed route view. This component needs to dynamically import and render the correct layout component based on the route's metadata.

Create a component named AppLayout.vue.

<!-- src/components/AppLayout.vue -->
<template>
  <!-- Render the correct layout dynamically -->
  <component :is="layoutComponent">
    <!-- Inject the current page view into the layout's <slot /> -->
    <router-view />
  </component>
</template>

<script setup>
import { computed, defineAsyncComponent } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

// Define a default layout name in case no meta field is provided
const DEFAULT_LAYOUT = 'DefaultLayout';

const layoutComponent = computed(() => {
  // Get the layout name from the current route's meta field, or use the default
  const layoutName = route.meta.layout || DEFAULT_LAYOUT;

  // Dynamically import the component from the layouts folder
  return defineAsyncComponent(() => import(`@/layouts/${layoutName}.vue`));
});
</script>

Step 3: Integrate into the Main App Instance

Now, we need to replace the standard <router-view /> in our main App.vue with our new AppLayout.vue component.

<!-- src/App.vue -->
<template>
  <!-- AppLayout dynamically handles which layout to display -->
  <AppLayout />
</template>

<script setup>
import AppLayout from './components/AppLayout.vue';
</script>

Step 4: Configure the Vue Router

Finally, configure your routes in src/router/index.js to specify which layout each page should use via the meta field.

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/HomePage.vue';
import Dashboard from '@/views/AdminDashboard.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    meta: { layout: 'DefaultLayout' } // Use the default site layout
  },
  {
    path: '/admin',
    name: 'AdminDashboard',
    component: Dashboard,
    meta: { layout: 'AdminLayout', requiresAuth: true } // Use the admin dashboard layout
  },
  // Add other routes here...
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

Summary of Benefits

This multi-layout system provides a robust and scalable architecture:

  1. Cleaner Routing: Layout information is co-located with the route definitions, not scattered in components.

  2. Reusable Layouts: Layout components act as wrappers that can be reused across many different views.

  3. Dynamic Imports: We use defineAsyncComponent and dynamic imports (import(...)) to only load the necessary layout files when they are needed, optimizing bundle size.

Implementing smart layouts for VueJS in this manner makes managing complex application UIs significantly easier and more intuitive for your development team.

If your organization is building enterprise-level Vue applications and you need expertise in structuring large-scale frontends, you might consider engaging specialized talent. You can hire vue.js developers who have experience implementing scalable architecture patterns like this to accelerate your project development.

More from this blog

Software & Tech

55 posts