5.6.8 • Published 6 months ago
Layout UI 组件
Layout UI 组件是一个基于 Vue 3 的高度可定制化布局组件,提供了多种布局模式,支持响应式设计、侧边栏折叠、头部固定等功能。
安装
npm install @cimom/vben-core-ui-kit-layout-ui
基本使用
<script setup lang="ts">
import { VbenLayout } from '@cimom/vben-core-ui-kit-layout-ui';
import { ref } from 'vue';
const sidebarCollapse = ref(false);
</script>
<template>
<VbenLayout v-model:sidebarCollapse="sidebarCollapse" layout="sidebar-nav">
<template #header>
<div>头部内容</div>
</template>
<template #sidebar>
<div>侧边栏内容</div>
</template>
<template #default>
<div>主要内容区域</div>
</template>
<template #footer>
<div>页脚内容</div>
</template>
</VbenLayout>
</template>
组件属性
VbenLayout Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| layout | string | 'sidebar-nav' | 布局模式 |
| headerHeight | number | 50 | 头部高度 |
| headerVisible | boolean | true | 头部是否可见 |
| headerHidden | boolean | false | 头部是否隐藏 |
| headerMode | string | 'fixed' | 头部模式,可选值: 'fixed', 'static', 'auto', 'auto-scroll' |
| headerToggleSidebarButton | boolean | true | 是否显示头部切换侧边栏按钮 |
| sidebarWidth | number | 180 | 侧边栏宽度 |
| sideCollapseWidth | number | 60 | 侧边栏折叠时的宽度 |
| sidebarMixedWidth | number | 80 | 混合模式下侧边栏宽度 |
| sidebarHidden | boolean | false | 侧边栏是否隐藏 |
| sidebarCollapsedButton | boolean | true | 是否显示侧边栏折叠按钮 |
| sidebarCollapseShowTitle | boolean | false | 侧边栏折叠时是否显示标题 |
| sidebarFixedButton | boolean | true | 是否显示侧边栏固定按钮 |
| sidebarTheme | string | 'dark' | 侧边栏主题 |
| sidebarExtraCollapsedWidth | number | 60 | 扩展侧边栏折叠时的宽度 |
| footerEnable | boolean | false | 是否启用页脚 |
| footerFixed | boolean | true | 页脚是否固定 |
| footerHeight | number | 32 | 页脚高度 |
| tabbarEnable | boolean | true | 是否启用标签栏 |
| tabbarHeight | number | 40 | 标签栏高度 |
| contentCompact | string | 'wide' | 内容区域紧凑模式 |
| contentCompactWidth | number | 1200 | 内容区域紧凑模式下的宽度 |
| contentPadding | number | 0 | 内容区域内边距 |
| contentPaddingTop | number | 0 | 内容区域上内边距 |
| contentPaddingRight | number | 0 | 内容区域右内边距 |
| contentPaddingBottom | number | 0 | 内容区域下内边距 |
| contentPaddingLeft | number | 0 | 内容区域左内边距 |
| isMobile | boolean | false | 是否为移动设备 |
| zIndex | number | 200 | z-index 值 |
v-model 绑定属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| sidebarCollapse | boolean | false | 侧边栏是否折叠 |
| sidebarEnable | boolean | true | 侧边栏是否启用 |
| sidebarExpandOnHover | boolean | false | 侧边栏是否在悬停时展开 |
| sidebarExtraVisible | boolean | - | 扩展侧边栏是否可见 |
| sidebarExtraCollapse | boolean | false | 扩展侧边栏是否折叠 |
事件
| 事件名 | 参数 | 说明 |
|---|
| sideMouseLeave | - | 鼠标离开侧边栏时触发 |
| toggleSidebar | - | 切换侧边栏时触发 |
插槽
| 插槽名 | 说明 |
|---|
| default | 默认插槽,用于放置主要内容 |
| header | 头部内容 |
| headerLeft | 头部左侧内容 |
| headerRight | 头部右侧内容 |
| sidebar | 侧边栏内容 |
| sidebarExtra | 扩展侧边栏内容 |
| tabbar | 标签栏内容 |
| footer | 页脚内容 |
布局模式
Layout UI 组件支持多种布局模式:
sidebar-nav: 侧边栏导航模式header-nav: 顶部导航模式mixed-nav: 混合导航模式sidebar-mixed-nav: 侧边栏混合导航模式header-mixed-nav: 顶部混合导航模式header-sidebar-nav: 顶部侧边栏导航模式full-content: 全屏内容模式
示例
侧边栏导航模式
<template>
<VbenLayout
v-model:sidebarCollapse="sidebarCollapse"
v-model:sidebarExpandOnHover="sidebarExpandOnHover"
layout="sidebar-nav"
:headerHeight="60"
:sidebarWidth="200"
:sideCollapseWidth="64"
>
<template #header>
<div class="flex h-full items-center px-4">
<h1 class="text-xl font-bold">管理系统</h1>
<div class="flex-1"></div>
<div class="flex items-center space-x-4">
<span>用户名</span>
<button>退出</button>
</div>
</div>
</template>
<template #sidebar>
<div class="p-2">
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">首页</div>
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">用户管理</div>
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">系统设置</div>
</div>
</template>
<template #default>
<div class="p-4">
<h2 class="mb-4 text-lg font-bold">内容区域</h2>
<p>这是主要内容区域</p>
</div>
</template>
<template #footer>
<div class="text-center text-sm text-gray-500">© 2025 管理系统</div>
</template>
</VbenLayout>
</template>
<script setup lang="ts">
import { VbenLayout } from '@cimom/vben-core-ui-kit-layout-ui';
import { ref } from 'vue';
const sidebarCollapse = ref(false);
const sidebarExpandOnHover = ref(true);
</script>
混合导航模式
<template>
<VbenLayout
v-model:sidebarCollapse="sidebarCollapse"
layout="mixed-nav"
:headerHeight="60"
:sidebarMixedWidth="80"
:sidebarWidth="200"
>
<template #header>
<div class="flex h-full items-center px-4">
<h1 class="text-xl font-bold">管理系统</h1>
<div class="flex-1"></div>
<div class="flex items-center space-x-4">
<span>用户名</span>
<button>退出</button>
</div>
</div>
</template>
<template #sidebar>
<div class="flex flex-col items-center py-4">
<div class="mb-4 cursor-pointer p-4">
<svg
class="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
></path>
</svg>
<div class="mt-1 text-xs">首页</div>
</div>
<div class="mb-4 cursor-pointer p-4">
<svg
class="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
></path>
</svg>
<div class="mt-1 text-xs">用户</div>
</div>
<div class="cursor-pointer p-4">
<svg
class="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
></path>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
></path>
</svg>
<div class="mt-1 text-xs">设置</div>
</div>
</div>
</template>
<template #sidebarExtra>
<div class="p-2">
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">用户列表</div>
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">角色管理</div>
<div class="mb-2 rounded px-4 py-2 hover:bg-gray-100">权限设置</div>
</div>
</template>
<template #default>
<div class="p-4">
<h2 class="mb-4 text-lg font-bold">用户管理</h2>
<p>这是用户管理页面的内容</p>
</div>
</template>
</VbenLayout>
</template>
<script setup lang="ts">
import { VbenLayout } from '@cimom/vben-core-ui-kit-layout-ui';
import { ref } from 'vue';
const sidebarCollapse = ref(false);
</script>
响应式布局
<template>
<VbenLayout
v-model:sidebarCollapse="sidebarCollapse"
layout="sidebar-nav"
:isMobile="isMobile"
:headerHeight="60"
:sidebarWidth="200"
:sideCollapseWidth="64"
>
<!-- 布局内容 -->
</VbenLayout>
</template>
<script setup lang="ts">
import { VbenLayout } from '@cimom/vben-core-ui-kit-layout-ui';
import { ref, onMounted, onUnmounted } from 'vue';
const sidebarCollapse = ref(false);
const isMobile = ref(false);
const checkIsMobile = () => {
isMobile.value = window.innerWidth < 768;
if (isMobile.value) {
sidebarCollapse.value = true;
}
};
onMounted(() => {
checkIsMobile();
window.addEventListener('resize', checkIsMobile);
});
onUnmounted(() => {
window.removeEventListener('resize', checkIsMobile);
});
</script>