Vue Router Layout Selector
Vue Router Layout is a lightweight utility designed for dynamically resolving layout components within Vue Router applications. Currently stable at version 0.4.1, the library provides a programmatic way to define layouts for routes by using a factory function, `createRouterLayout`, which then generates a `<RouterLayout>` component. This component is subsequently integrated into Vue Router's `routes` configuration. The package supports dynamic imports for layout components, enabling efficient code splitting. A key differentiator is its focus on minimalist layout resolution, allowing developers to specify layouts directly within their page components via a `layout` option, including passing props since v0.4.0. Its release cadence is irregular but consistent with bug fixes and features. Crucially, version 0.2.0 marked a breaking change by dropping Vue 2 support in favor of Vue 3, necessitating version awareness for project compatibility. For more comprehensive routing solutions, the author points to `vue-cli-plugin-auto-routing`.
Common errors
-
TypeError: app.use is not a function
cause Attempting to use `vue-router-layout` v0.2.0+ (designed for Vue 3) in a Vue 2 project, where `app.use` syntax is not available.fixDowngrade `vue-router-layout` to `0.1.x` for Vue 2 projects, or upgrade your entire project to Vue 3. -
Property 'layout' does not exist on type 'ComponentOptionsBase<any, any, any, any, any, any, any, any, any>'.
cause TypeScript compiler error when using the custom `layout` option within a Vue component's options API, as the type definitions do not automatically include this custom property.fixAugment Vue's `ComponentCustomOptions` interface to declare the `layout` property. For example: `declare module '@vue/runtime-core' { interface ComponentCustomOptions { layout?: string | { name: string; props?: Record<string, any> }; } }` -
Layout component does not update or render correctly after route navigation, especially with lazy-loaded components.
cause Older versions of `vue-router-layout` had known bugs related to the reactivity and lifecycle of dynamically loaded components within the layout system.fixUpgrade `vue-router-layout` to version `0.3.0` or higher, which includes significant improvements for handling lazy component loading and ensuring proper layout updates.
Warnings
- breaking Version 0.2.0 and later drops support for Vue 2, requiring Vue 3 or higher. Projects on Vue 2 must use `vue-router-layout@0.1.x`.
- gotcha The `created` hook in page components could be wrongly called when the layout changes, leading to unintended side effects or re-initialization.
- gotcha Prior to v0.4.0, directly passing props to layout components via the `layout` option in route meta or component options was not supported, limiting layout reusability.
- gotcha Initial versions (`<0.3.0`) had issues with lifecycle hooks or layout updates when using async components for pages or layouts, potentially leading to incorrect rendering or hook calls and requiring manual workarounds.
Install
-
npm install vue-router-layout -
yarn add vue-router-layout -
pnpm add vue-router-layout
Imports
- createRouterLayout
const createRouterLayout = require('vue-router-layout')import { createRouterLayout } from 'vue-router-layout' - LayoutResolver
import type { LayoutResolver } from 'vue-router-layout' - RouterLayoutOptions
import type { RouterLayoutOptions } from 'vue-router-layout'
Quickstart
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { createRouterLayout } from 'vue-router-layout';
// Define your layout components
const DefaultLayout = { template: '<div><h1>Default Layout</h1><router-view /></div>' };
const AdminLayout = { template: '<div><h2>Admin Panel Layout</h2><router-view /></div>' };
// Create <RouterLayout> component.
const RouterLayout = createRouterLayout(layout => {
if (layout === 'admin') {
return Promise.resolve(AdminLayout);
}
return Promise.resolve(DefaultLayout);
});
const routes = [
{
path: '/',
component: RouterLayout,
children: [
{
path: '',
component: { template: '<p>Home Page</p>', layout: 'default' },
},
{
path: 'dashboard',
component: { template: '<p>Admin Dashboard</p>', layout: { name: 'admin', props: { title: 'Admin' } } },
},
{
path: 'profile',
component: { template: '<p>User Profile</p>', layout: 'default' },
},
],
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
const app = createApp({});
app.use(router);
app.mount('#app');
// For a real application, you would render this in an HTML file:
// <div id="app"></div>
// <router-view></router-view>