Skip to content

QuiLayout 布局

QuiLayout 是一个基于 Naive UI 的高度可配置的布局组件,提供了多种常见的后台管理系统布局模式,并集成了路由菜单自动生成、面包屑导航、动态路由管理等功能。

基础用法

1. 定义布局存储

推荐使用 Pinia 来管理布局状态,利用 useLayout 组合式函数初始化布局配置。

ts
// stores/layout.ts
import { defineStore } from 'pinia'
import { useLayout } from '@quiteer/naive-extra'
import router, { routes } from '@/router'

export const useLayoutStore = defineStore('layout', () => {
  const {
    collapsed,
    activeKey,
    menuOptions,
    type,
    baseRoutes,
    addRoute,
    removeRoute,
    // ...其他状态
  } = useLayout({
    baseRoutes: routes,
    router,
    initialActiveKey: '/',
    type: 'side-menu', // 默认布局类型
    // ...其他配置
  })

  return {
    collapsed,
    activeKey,
    menuOptions,
    type,
    baseRoutes,
    addRoute,
    removeRoute,
    // ...
  }
})

2. 使用组件

在你的应用主布局文件中引入 QuiLayout 并绑定状态。

vue
<!-- layout/index.vue -->
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { QuiLayout } from '@quiteer/naive-extra'
import { useLayoutStore } from '@/stores/layout'

const layoutStore = useLayoutStore()
const {
  collapsed,
  activeKey,
  menuOptions,
  type,
  baseRoutes,
  inverted,
  bordered,
  headerHeight,
  footerHeight,
  siderWidth,
  collapsedWidth
} = storeToRefs(layoutStore)
</script>

<template>
  <QuiLayout
    v-model:is-collapsed="collapsed"
    v-model:active-key="activeKey"
    v-model:inverted="inverted"
    :type="type"
    :base-routes="baseRoutes"
    :menu-options="menuOptions"
    :bordered="bordered"
    :header-height="headerHeight"
    :footer-height="footerHeight"
    :sider-width="siderWidth"
    :collapsed-width="collapsedWidth"
  />
</template>

布局模式 (Layout Types)

QuiLayout 支持多种布局模式,通过 type 属性进行切换。

类型名称描述
side-menu左侧菜单布局左侧菜单布局,左侧为垂直导航菜单,右侧为主内容区
side-menu/2左侧-顶部菜单布局左侧为垂直导航菜单,顶部为水平导航菜单,下方为主内容区
side-mixed-menu/2左侧混合-顶部菜单布局左侧为垂直导航菜单,顶部为水平导航菜单,下方为主内容区
top-menu顶部菜单布局无侧边栏,顶部为水平导航菜单,下方为主内容区
top-menu/2顶部-左侧菜单布局顶部菜单为主,顶部为水平导航菜单,左侧为垂直导航菜单,下方为主内容区
top-mixed-menu/2顶部-左侧混合菜单布局顶部菜单为主,顶部为水平导航菜单,左侧为垂直导航菜单,下方为主内容区
blank无菜单布局无菜单布局,页面不包含任何主导航菜单,适用于登录页、引导页、全屏应用等场景

注意:带 /2 后缀的混合模式支持双菜单联动(Main Menu & Sub Menu),组件内部会自动处理 activeKey 的同步与解析,实现一级菜单与二级菜单的分离展示与联动。

API 参考

QuiLayout Props

属性名类型默认值说明
typeLayoutType'side-menu'布局类型
baseRoutesRouteRecordRaw[][]基础路由表,用于生成菜单
menuOptionsMenuOption[][]菜单选项数据
activeKeystring'/'当前激活的菜单 Key (v-model)
isCollapsedbooleanfalse侧边栏是否折叠 (v-model)
invertedbooleanfalse是否反色主题 (v-model)
borderedbooleantrue是否显示边框
headerHeightnumber54头部高度
footerHeightnumber42底部高度
footerFullbooleantrue底部是否占满宽度
showFooterbooleantrue是否显示底部
siderWidthnumber220侧边栏宽度
siderMixedWidthnumber80侧边栏混合模式宽度
collapsedWidthnumber60侧边栏折叠后宽度
accordionbooleantrue是否开启手风琴模式

默认配置

QuiLayout 默认值(来自 DEFAULT_LAYOUT_PROPS):

ts
{
  type: 'side-menu',
  bordered: true,
  inverted: false,
  isCollapsed: false,
  showFooter: true,
  headerHeight: 54,
  footerHeight: 42,
  footerFull: true,
  siderWidth: 220,
  siderMixedWidth: 80,
  collapsedWidth: 60,
  activeKey: '/',
  menuOptions: [],
  accordion: true
}

useLayout 返回值

useLayout 提供了布局所需的状态管理和工具方法。

属性/方法类型说明
activeKeyRef<string>当前激活的路由路径
setActiveKey(key: string) => void设置激活路径
collapsedRef<boolean>侧边栏折叠状态
setCollapsed(v: boolean) => void设置折叠状态
toggle() => void切换折叠状态
typeRef<LayoutType>当前布局类型
menuOptionsComputedRef<MenuOption[]>根据路由生成的菜单选项
addRoute(route: RouteRecordRaw) => void动态添加路由,并自动更新菜单
removeRoute(name: string) => void动态移除路由
addRoutes(routes: RouteRecordRaw[]) => void批量添加路由

useLayout 参数

参数类型说明
baseRoutesRouteRecordRaw[] | Ref<RouteRecordRaw[]>基础路由表
routerRouter显式传入路由实例,确保在 Store 中可用
routeRouteLocationNormalizedLoaded可选,显式传入当前路由
menuOptionsMenuOption[] | Ref<MenuOption[]>菜单数据,传入后优先使用
initialActiveKeystring初始激活菜单 key
typeLayoutType布局类型

动态路由管理

QuiLayout 深度集成了 vue-router,通过 useLayout 提供的 addRouteremoveRoute 方法,可以轻松实现动态路由的添加与删除,且菜单会自动更新。

添加路由示例

ts
const { addRoute } = useLayoutStore()

function addDynamicPage() {
  addRoute({
    path: '/dynamic-page',
    name: 'DynamicPage',
    meta: {
      title: '动态页面',
      icon: 'mdi:flash'
    },
    component: () => import('@/pages/DynamicPage.vue')
  })
}

移除路由示例

ts
const { removeRoute } = useLayoutStore()

function removeDynamicPage() {
  removeRoute('DynamicPage')
}

功能特性

  • 自动菜单生成:根据传入的 baseRoutes 自动生成符合 Naive UI 格式的菜单选项。
  • 面包屑导航:在 side-menu 等模式下自动生成面包屑。
  • 布局切换联动:在单栏菜单(如 side-menu)与双栏菜单(如 top-mixed-menu/2)切换时,自动解析并同步 activeKey,保持选中状态一致。
  • 响应式适配:支持配置侧边栏宽度、头部高度等尺寸。
  • Vue Router 同步activeKey 会自动跟随路由变化,点击菜单也会自动触发路由跳转。

Released under the MIT License.