1.vue router里的Layout到底是个啥?
做Vue项目时,你有没有遇到过“每个页面都要重复写导航栏、侧边栏”的烦恼?或者登录页和后台页需要完全不同的页面结构,不知道咋拆分?这时候就得聊聊vue - router里的Layout怎么玩了,Layout看似是个简单的布局概念,实际能帮我们解决页面结构复用、项目维护性的大问题,下面从基础到实战,一步步把Layout的门道理清楚。
你可以把Layout理解成“页面的骨架”,比如做后台管理系统时,左边是侧边栏菜单、顶部是面包屑和用户信息、中间一大块是页面内容 —— 这整套结构就是Layout,它本质是个Vue组件,里面会放`举个例子:新建一个MainLayout.vue,里面写好侧边栏、顶栏的HTML和逻辑,然后在模板里留个<router - view/>,之后所有后台页面(比如订单列表、用户管理)都作为这个Layout的“子内容”,路由切换时,只有<router - view>变,侧边栏、顶栏始终在那儿,这样就不用每个页面都重复写导航代码了。
为啥非要单独搞个Layout?直接写页面不行吗?
要是项目只有三五个页面,直接写确实没毛病,但页面一多,问题就来了:
- 重复代码恶心人:导航栏、页脚、权限校验逻辑,每个页面都复制粘贴?改个导航菜单得改十几个文件,这谁顶得住!
- 结构维护难:登录页不需要导航,后台页需要;营销页要大横幅,内页要侧边栏…不同页面结构差异大时,全写在页面里会让代码乱成一锅粥。
- 团队协作效率低:UI同学改个公共样式,得每个页面找一遍;前端新人接手,得在一堆页面里找公共部分在哪,头都大了。
而Layout把“公共骨架”和“页面内容”拆分开,骨架只写一次,内容只关心业务 —— 复用性、维护性直接提升好几个档次。
手把手配置:vue - router里的Layout咋用?
步骤1:创建Layout组件
先建个布局组件,比如src/layouts/MainLayout.vue:
<template>
<div class="main - layout">
<!-- 侧边栏 -->
<aside class="sidebar">
<SidebarMenu /> <!-- 假设这是封装好的菜单组件 -->
</aside>
<!-- 主体区域 -->
<div class="main - content">
<TopBar /> <!-- 顶栏组件 -->
<router - view /> <!-- 关键!这里渲染子页面 -->
</div>
</div>
</template>
步骤2:在路由里配置父路由 + 子路由
打开src/router/index.js,把Layout作为父路由,子路由对应具体页面:
import { createRouter, createWebHashHistory } from 'vue - router'
import MainLayout from '@/layouts/MainLayout.vue'
import Dashboard from '@/views/Dashboard.vue'
import UserList from '@/views/UserList.vue'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/admin',
component: MainLayout, // 父路由用Layout
children: [ // 子路由们
{ path: 'dashboard', component: Dashboard },
{ path: 'users', component: UserList },
]
}
]
})
这样,当访问/admin/dashboard时,MainLayout会被渲染,Dashboard组件插入到MainLayout的<router - view>里,侧边栏、顶栏自然就跟着出现了。
复杂场景:Layout里的嵌套路由咋处理?
如果Layout里的侧边栏菜单还要分二级导航(订单管理”下有“订单列表”“退款列表”),这时候需要嵌套路由 + Layout内的<router - view>。
给MainLayout里的侧边栏再加个<router - view>,用来渲染二级页面:
<!-- MainLayout.vue 里新增二级路由出口 -->
<template>
<div class="main - layout">
<aside class="sidebar">
<SidebarMenu />
</aside>
<div class="main - content">
<TopBar />
<router - view name="secondary" /> <!-- 命名视图,渲染二级内容 -->
</div>
</div>
</template>
然后在路由里配置嵌套:
routes: [
{
path: '/admin',
component: MainLayout,
children: [
{
path: 'orders',
component: OrdersLayout, // 假设这是二级Layout(包含订单相关的公共结构)
children: [
{ path: 'list', component: OrderList, meta: { layoutOutlet: 'secondary' } },
{ path: 'refund', component: RefundList, meta: { layoutOutlet: 'secondary' } },
]
}
]
}
]
这里用了命名视图和meta标记,让二级页面精准渲染到Layout里的指定<router - view>,实现多层嵌套布局。
不同页面要不同Layout,咋搞?
比如登录页、404页不需要后台Layout,营销首页要大横幅Layout,后台页要侧边栏Layout,这时候得搞多Layout方案:
方法1:路由meta指定Layout
先建多个Layout:PublicLayout.vue(放营销页布局)、AuthLayout.vue(登录注册页布局)、MainLayout.vue(后台布局)。
然后在路由里用meta标记需要的Layout:
routes: [
{
path: '/',
component: PublicLayout,
children: [{ path: '', component: HomePage }]
},
{
path: '/login',
component: AuthLayout,
children: [{ path: '', component: LoginPage }]
},
{
path: '/admin',
component: MainLayout,
meta: { requiresAuth: true },
children: [...]
}
]
方法2:全局路由守卫动态选Layout
如果页面是否需要Layout要根据权限、角色判断(比如普通用户和管理员用不同Layout),可以在router.beforeEach里处理:
router.beforeEach((to, from, next) => {
const layoutComponent = determineLayout(to) // 自定义方法,根据to的信息选Layout
to.meta.layout = layoutComponent
next()
})
然后在App.vue里动态渲染Layout:
<template>
<component :is="currentLayout">
<router - view />
</component>
</template>
<script setup>
import { computed } from 'vue'
import { useRoute } from 'vue - router'
import MainLayout from '@/layouts/MainLayout.vue'
import PublicLayout from '@/layouts/PublicLayout.vue'
const route = useRoute()
const currentLayout = computed(() => {
return route.meta.layout || MainLayout // 默认用MainLayout
})
</script>
这样,不同路由就能自动匹配不同Layout,灵活应对多布局场景。
实战优化:Layout性能和维护咋兼顾?
优化1:异步加载Layout
把Layout写成异步组件,减少首屏加载体积:
const MainLayout = () => import('@/layouts/MainLayout.vue')
优化2:用keep - alive缓存Layout内组件
如果Layout里的侧边栏、顶栏有频繁切换的tab页,用<keep - alive>缓存<router - view>,避免重复渲染:
<template>
<div class="main - layout">
<aside class="sidebar"><SidebarMenu /></aside>
<div class="main - content">
<TopBar />
<keep - alive>
<router - view />
</keep - alive>
</div>
</div>
</template>
优化3:拆分Layout为原子组件
把侧边栏、顶栏、面包屑这些公共部分拆成单独的小组件(比如SidebarMenu.vue、TopBar.vue),让Layout只负责“组装”,代码更易维护:
<template>
<div class="main - layout">
<SidebarMenu :menus="menus" />
<div class="main - content">
<TopBar :user="user" />
<Breadcrumb :routes="routes" />
<router - view />
</div>
</div>
</template>
看完这些,你应该能明白:Layout是vue - router里“偷懒又高效”的布局方案 —— 用组件化思维把公共结构抽出来,让页面只关心业务,不管是简单的后台系统,还是复杂的多布局官网,掌握Layout的配置、嵌套、动态切换,项目结构会清爽很多,下次写项目时,别再把导航栏复制十遍了,试试Layout,效率直接拉满~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。