5.6.13 • Published 5 months ago

@cimom/vben-effects-layouts v5.6.13

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

@cimom/vben-effects-layouts

提供多种布局组件和布局系统,用于构建管理系统的整体页面结构。该包继承了核心布局组件的能力,并扩展了更多业务场景下的布局方案。

安装

# 进入目标应用目录,例如 apps/xxxx-app
# cd apps/xxxx-app
pnpm add @cimom/vben-effects-layouts

基本使用

// 导入布局组件
import {
  BasicLayout,
  AuthenticationLayout,
  IframeLayout,
} from '@cimom/vben-effects-layouts';

// 导入布局小部件
import {
  HeaderLogo,
  HeaderMenu,
  SideMenu,
  TabBar,
} from '@cimom/vben-effects-layouts';

布局类型

BasicLayout 基础布局

提供标准的管理系统布局,包含顶部导航栏、侧边菜单、标签页和内容区域。

<template>
  <BasicLayout>
    <template #header-left-1>
      <HeaderLogo />
    </template>
    <template #header-left-2>
      <HeaderMenu />
    </template>
    <template #header-right-1>
      <ThemeToggle />
    </template>
    <template #header-right-2>
      <UserDropdown />
    </template>

    <!-- 路由视图 -->
    <router-view />
  </BasicLayout>
</template>

<script setup lang="ts">
import {
  BasicLayout,
  HeaderLogo,
  HeaderMenu,
  ThemeToggle,
  UserDropdown,
} from '@cimom/vben-effects-layouts';
</script>

插槽说明

BasicLayout 提供了丰富的插槽,用于自定义布局的各个部分:

  • header-left-n: 顶部导航栏左侧插槽,n 为 0-19 的数字,breadcrumb 为 21-x
  • header-right-n: 顶部导航栏右侧插槽,n 为 0-49,其他特定组件有固定范围:
    • global-search: 50
    • theme-toggle: 51-59
    • language-toggle: 61-69
    • fullscreen: 71-79
    • notification: 81-89
    • user-dropdown: 91-149
    • 其他自定义组件: 151-x
  • menu: 自定义整个菜单区域
  • footer: 自定义页脚区域
  • content: 自定义内容区域
  • tabbar: 自定义标签页区域

属性说明

属性类型默认值说明
showLogobooleantrue是否显示 Logo
showFooterbooleantrue是否显示页脚
showBreadcrumbbooleantrue是否显示面包屑
showTabsbooleantrue是否显示标签页
showSidebarbooleantrue是否显示侧边栏
showHeaderbooleantrue是否显示顶部导航栏
fixedHeaderbooleantrue是否固定顶部导航栏
fixedSidebarbooleantrue是否固定侧边栏
contentMode'full' \| 'fixed''fixed'内容区域模式
menuMode'vertical' \| 'horizontal' \| 'inline''vertical'菜单模式
menuTheme'light' \| 'dark''light'菜单主题
menuWidthnumber210菜单宽度
collapsedWidthnumber48菜单折叠时的宽度
collapsedbooleanfalse是否折叠菜单

AuthenticationLayout 认证布局

提供登录、注册、找回密码等认证页面的布局。

<template>
  <AuthenticationLayout
    :title="title"
    :desc="desc"
    :backgroundUrl="backgroundUrl"
  >
    <LoginForm @login="handleLogin" />
  </AuthenticationLayout>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { AuthenticationLayout } from '@cimom/vben-effects-layouts';
import { LoginForm } from '@/components/login-form';

const title = ref('系统登录');
const desc = ref('欢迎使用管理系统');
const backgroundUrl = ref('/images/login-bg.jpg');

const handleLogin = (formData) => {
  // 处理登录逻辑
};
</script>

属性说明

属性类型默认值说明
titlestring''标题
descstring''描述文本
backgroundUrlstring''背景图片 URL
logoUrlstring''Logo URL
showLanguageTogglebooleantrue是否显示语言切换
showThemeTogglebooleantrue是否显示主题切换

IframeLayout Iframe 布局

提供嵌入外部网页的布局。

<template>
  <IframeLayout :src="iframeSrc" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { IframeLayout } from '@cimom/vben-effects-layouts';

const iframeSrc = ref('https://example.com');
</script>

属性说明

属性类型默认值说明
srcstring''iframe 的 src 属性
loadingbooleanfalse是否显示加载状态
heightstring \| number'100%'iframe 高度
widthstring \| number'100%'iframe 宽度

布局小部件

顶部导航栏组件

HeaderLogo 顶部 Logo

<template>
  <HeaderLogo :showTitle="true" :logo="logoUrl" :title="title" />
</template>

<script setup lang="ts">
import { HeaderLogo } from '@cimom/vben-effects-layouts';

const logoUrl = '/logo.png';
const title = '管理系统';
</script>

HeaderMenu 顶部菜单

<template>
  <HeaderMenu :menus="menus" />
</template>

<script setup lang="ts">
import { HeaderMenu } from '@cimom/vben-effects-layouts';

const menus = [
  {
    path: '/dashboard',
    title: '仪表盘',
    icon: 'dashboard',
  },
  {
    path: '/system',
    title: '系统管理',
    icon: 'setting',
    children: [
      {
        path: '/system/user',
        title: '用户管理',
      },
      {
        path: '/system/role',
        title: '角色管理',
      },
    ],
  },
];
</script>

Breadcrumb 面包屑

<template>
  <Breadcrumb :items="breadcrumbItems" />
</template>

<script setup lang="ts">
import { Breadcrumb } from '@cimom/vben-effects-layouts';

const breadcrumbItems = [
  { title: '首页', path: '/' },
  { title: '系统管理', path: '/system' },
  { title: '用户管理', path: '/system/user' },
];
</script>

侧边栏组件

SideMenu 侧边菜单

<template>
  <SideMenu
    :menus="menus"
    :collapsed="collapsed"
    :theme="menuTheme"
    @select="handleMenuSelect"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { SideMenu } from '@cimom/vben-effects-layouts';

const collapsed = ref(false);
const menuTheme = ref('light');

const menus = [
  // 菜单数据...
];

const handleMenuSelect = (key) => {
  console.log('Selected menu:', key);
};
</script>

标签页组件

TabBar 标签页

<template>
  <TabBar
    :tabs="tabs"
    :activeKey="activeTabKey"
    @change="handleTabChange"
    @close="handleTabClose"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { TabBar } from '@cimom/vben-effects-layouts';

const tabs = ref([
  { key: '/dashboard', title: '仪表盘' },
  { key: '/system/user', title: '用户管理' },
]);
const activeTabKey = ref('/dashboard');

const handleTabChange = (key) => {
  activeTabKey.value = key;
};

const handleTabClose = (key) => {
  tabs.value = tabs.value.filter((tab) => tab.key !== key);
};
</script>

其他组件

ThemeToggle 主题切换

<template>
  <ThemeToggle />
</template>

<script setup lang="ts">
import { ThemeToggle } from '@cimom/vben-effects-layouts';
</script>

LanguageToggle 语言切换

<template>
  <LanguageToggle />
</template>

<script setup lang="ts">
import { LanguageToggle } from '@cimom/vben-effects-layouts';
</script>

FullscreenToggle 全屏切换

<template>
  <FullscreenToggle />
</template>

<script setup lang="ts">
import { FullscreenToggle } from '@cimom/vben-effects-layouts';
</script>

UserDropdown 用户下拉菜单

<template>
  <UserDropdown :user="user" @logout="handleLogout" />
</template>

<script setup lang="ts">
import { UserDropdown } from '@cimom/vben-effects-layouts';

const user = {
  name: 'Admin',
  avatar: '/avatar.jpg',
};

const handleLogout = () => {
  // 处理登出逻辑
};
</script>

高级用法

自定义布局

通过组合使用布局组件和小部件,可以创建自定义的布局:

<template>
  <BasicLayout
    :menuMode="menuMode"
    :collapsed="collapsed"
    :showTabs="showTabs"
    :showFooter="showFooter"
  >
    <!-- 自定义顶部左侧区域 -->
    <template #header-left-1>
      <HeaderLogo :showTitle="!collapsed" />
    </template>
    <template #header-left-2>
      <Breadcrumb v-if="menuMode === 'vertical'" />
      <HeaderMenu v-else :menus="menus" />
    </template>

    <!-- 自定义顶部右侧区域 -->
    <template #header-right-1>
      <FullscreenToggle />
    </template>
    <template #header-right-2>
      <ThemeToggle />
    </template>
    <template #header-right-3>
      <LanguageToggle />
    </template>
    <template #header-right-4>
      <UserDropdown :user="user" @logout="handleLogout" />
    </template>

    <!-- 自定义页脚 -->
    <template #footer>
      <div class="custom-footer">
        © {{ new Date().getFullYear() }} My Company
      </div>
    </template>

    <!-- 路由视图 -->
    <router-view v-slot="{ Component }">
      <transition name="fade" mode="out-in">
        <component :is="Component" />
      </transition>
    </router-view>
  </BasicLayout>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import {
  BasicLayout,
  HeaderLogo,
  Breadcrumb,
  HeaderMenu,
  FullscreenToggle,
  ThemeToggle,
  LanguageToggle,
  UserDropdown,
} from '@cimom/vben-effects-layouts';

const menuMode = ref('vertical');
const collapsed = ref(false);
const showTabs = ref(true);
const showFooter = ref(true);
const menus = [
  /* 菜单数据 */
];
const user = { name: 'Admin', avatar: '/avatar.jpg' };

const handleLogout = () => {
  // 处理登出逻辑
};
</script>

<style scoped>
.custom-footer {
  text-align: center;
  padding: 16px;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

响应式布局

布局组件支持响应式设计,可以根据屏幕尺寸自动调整:

<template>
  <BasicLayout
    :menuMode="isMobile ? 'vertical' : menuMode"
    :collapsed="isMobile || collapsed"
    :showTabs="!isMobile && showTabs"
  >
    <!-- 布局内容 -->
  </BasicLayout>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { BasicLayout } from '@cimom/vben-effects-layouts';
import { useIsMobile } from '@cimom/vben-effects-hooks';

const menuMode = ref('horizontal');
const collapsed = ref(false);
const showTabs = ref(true);
const { isMobile } = useIsMobile();
</script>

动态切换布局

可以根据路由或用户偏好动态切换布局:

<template>
  <component :is="layoutComponent">
    <router-view />
  </component>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import {
  BasicLayout,
  AuthenticationLayout,
  IframeLayout,
} from '@cimom/vben-effects-layouts';

const route = useRoute();

const layoutComponent = computed(() => {
  const layoutType = route.meta.layout;

  switch (layoutType) {
    case 'auth':
      return AuthenticationLayout;
    case 'iframe':
      return IframeLayout;
    default:
      return BasicLayout;
  }
});
</script>

与其他包的集成

与 @cimom/vben-stores 集成

<script setup lang="ts">
import { BasicLayout } from '@cimom/vben-effects-layouts';
import { useUserStore, useMenuStore, useTabStore } from '@cimom/vben-stores';

const userStore = useUserStore();
const menuStore = useMenuStore();
const tabStore = useTabStore();

// 使用 store 中的数据
const menus = menuStore.menus;
const tabs = tabStore.tabs;
const user = userStore.userInfo;
</script>

与 @cimom/vben-preferences 集成

<script setup lang="ts">
import { BasicLayout } from '@cimom/vben-effects-layouts';
import { usePreferences } from '@cimom/vben-preferences';

const { preferences, updatePreferences } = usePreferences();

// 根据用户偏好设置布局
const menuMode = computed(() => preferences.menuMode || 'vertical');
const menuTheme = computed(() => preferences.menuTheme || 'light');
const collapsed = computed(() => preferences.collapsed || false);

// 更新用户偏好
const toggleCollapsed = () => {
  updatePreferences({
    collapsed: !collapsed.value,
  });
};
</script>

注意事项

  1. 布局组件依赖于多个核心组件包,确保它们已正确安装。
  2. 使用 BasicLayout 时,建议在路由配置中设置相应的元数据,以便自动生成面包屑和标签页。
  3. 响应式布局需要配合 @cimom/vben-effects-hooks 中的 useIsMobile 等钩子使用。
  4. 自定义插槽时,注意插槽名称的命名规则,特别是顶部导航栏的左右侧插槽。

常见问题

布局组件不显示或样式错乱

确保已正确导入样式文件,可以在入口文件中全局导入:

// main.ts
import '@cimom/vben-effects-layouts/dist/style.css';

菜单项不显示

检查菜单数据格式是否正确,以及是否与路由配置匹配:

// 正确的菜单数据格式
const menus = [
  {
    path: '/dashboard',
    title: '仪表盘',
    icon: 'dashboard',
  },
  {
    path: '/system',
    title: '系统管理',
    icon: 'setting',
    children: [
      {
        path: '/system/user',
        title: '用户管理',
      },
    ],
  },
];

标签页不自动生成

确保路由配置中包含正确的元数据:

// router.ts
const routes = [
  {
    path: '/dashboard',
    component: () => import('./views/dashboard/index.vue'),
    meta: {
      title: '仪表盘',
      icon: 'dashboard',
      affix: true, // 固定标签页
    },
  },
];