npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cimom/vben-effects-layouts

v5.6.13

Published

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

Readme

@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: 自定义标签页区域

属性说明

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | showLogo | boolean | true | 是否显示 Logo | | showFooter | boolean | true | 是否显示页脚 | | showBreadcrumb | boolean | true | 是否显示面包屑 | | showTabs | boolean | true | 是否显示标签页 | | showSidebar | boolean | true | 是否显示侧边栏 | | showHeader | boolean | true | 是否显示顶部导航栏 | | fixedHeader | boolean | true | 是否固定顶部导航栏 | | fixedSidebar | boolean | true | 是否固定侧边栏 | | contentMode | 'full' \| 'fixed' | 'fixed' | 内容区域模式 | | menuMode | 'vertical' \| 'horizontal' \| 'inline' | 'vertical' | 菜单模式 | | menuTheme | 'light' \| 'dark' | 'light' | 菜单主题 | | menuWidth | number | 210 | 菜单宽度 | | collapsedWidth | number | 48 | 菜单折叠时的宽度 | | collapsed | boolean | false | 是否折叠菜单 |

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>

属性说明

| 属性 | 类型 | 默认值 | 说明 | | -------------------- | --------- | ------ | ---------------- | | title | string | '' | 标题 | | desc | string | '' | 描述文本 | | backgroundUrl | string | '' | 背景图片 URL | | logoUrl | string | '' | Logo URL | | showLanguageToggle | boolean | true | 是否显示语言切换 | | showThemeToggle | boolean | true | 是否显示主题切换 |

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>

属性说明

| 属性 | 类型 | 默认值 | 说明 | | --------- | ------------------ | -------- | ------------------ | | src | string | '' | iframe 的 src 属性 | | loading | boolean | false | 是否显示加载状态 | | height | string \| number | '100%' | iframe 高度 | | width | string \| 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, // 固定标签页
    },
  },
];