Code前端首页关于Code前端联系我们

1.vue router里的Layout到底是个啥?

terry 9小时前 阅读数 10 #Vue
文章标签 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.vueTopBar.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前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门