5.6.10 • Published 4 months ago
@cimom/vben-effects-common-ui v5.6.10
@cimom/vben-effects-common-ui
通用 UI 组件库,提供了一系列可复用的 UI 组件和页面模板,用于快速构建管理系统界面。该包继承了核心 UI 组件库的能力,并扩展了更多业务场景下的组件。
安装
# 进入目标应用目录,例如 apps/xxxx-app
# cd apps/xxxx-app
pnpm add @cimom/vben-effects-common-ui
基本使用
// 导入所有组件
import {
ApiSelect,
Captcha,
ColPage,
CountTo,
EllipsisText,
IconPicker,
JsonViewer,
Loading,
Page,
Resize,
Tippy,
} from '@cimom/vben-effects-common-ui';
// 导入特定组件
import { Captcha } from '@cimom/vben-effects-common-ui';
import { Loading } from '@cimom/vben-effects-common-ui/es/loading';
import { Tippy } from '@cimom/vben-effects-common-ui/es/tippy';
组件列表
基础组件
ApiComponent 系列
基于 API 请求的组件,用于从后端获取数据并渲染。
<template>
<div>
<ApiSelect
:api="getUserList"
labelField="name"
valueField="id"
placeholder="请选择用户"
@change="handleChange"
/>
</div>
</template>
<script setup lang="ts">
import { ApiSelect } from '@cimom/vben-effects-common-ui';
import { getUserList } from '@/api/user';
const handleChange = (value) => {
console.log('Selected value:', value);
};
</script>
Captcha 验证码
用于显示和刷新验证码的组件。
<template>
<div>
<Captcha @refresh="handleRefresh" @verify="handleVerify" />
</div>
</template>
<script setup lang="ts">
import { Captcha } from '@cimom/vben-effects-common-ui';
const handleRefresh = () => {
console.log('Refreshing captcha...');
};
const handleVerify = (code: string) => {
console.log('Verifying captcha code:', code);
};
</script>
ColPage 列页面
用于创建具有列布局的页面。
<template>
<div>
<ColPage :span="12">
<template #left>
<div>左侧内容</div>
</template>
<template #right>
<div>右侧内容</div>
</template>
</ColPage>
</div>
</template>
<script setup lang="ts">
import { ColPage } from '@cimom/vben-effects-common-ui';
</script>
CountTo 数字动画
用于创建数字变化的动画效果。
<template>
<div>
<CountTo :startVal="0" :endVal="2000" :duration="2000" />
</div>
</template>
<script setup lang="ts">
import { CountTo } from '@cimom/vben-effects-common-ui';
</script>
EllipsisText 文本省略
用于显示带有省略号的长文本。
<template>
<div>
<EllipsisText :text="longText" :len="50" />
</div>
</template>
<script setup lang="ts">
import { EllipsisText } from '@cimom/vben-effects-common-ui';
const longText = '这是一段非常长的文本,当超出指定长度时会显示省略号...';
</script>
IconPicker 图标选择器
用于选择图标的组件。
<template>
<div>
<IconPicker v-model:value="icon" @change="handleChange" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { IconPicker } from '@cimom/vben-effects-common-ui';
const icon = ref('mdi:home');
const handleChange = (newIcon: string) => {
console.log('Selected icon:', newIcon);
};
</script>
JsonViewer JSON 查看器
用于格式化显示 JSON 数据的组件。
<template>
<div>
<JsonViewer :value="jsonData" />
</div>
</template>
<script setup lang="ts">
import { JsonViewer } from '@cimom/vben-effects-common-ui';
const jsonData = {
name: 'John Doe',
age: 30,
address: {
city: 'New York',
country: 'USA',
},
skills: ['JavaScript', 'Vue', 'React'],
};
</script>
Loading 加载
用于显示加载状态的组件。
<template>
<div>
<Loading :loading="isLoading" :tip="loadingTip">
<div>加载完成后显示的内容</div>
</Loading>
<!-- 全屏加载 -->
<button @click="showFullScreenLoading">显示全屏加载</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Loading, useLoading } from '@cimom/vben-effects-common-ui';
const isLoading = ref(true);
const loadingTip = ref('加载中...');
// 全屏加载
const { openFullLoading, closeFullLoading } = useLoading();
const showFullScreenLoading = () => {
openFullLoading();
setTimeout(() => {
closeFullLoading();
}, 3000);
};
// 模拟加载完成
setTimeout(() => {
isLoading.value = false;
}, 2000);
</script>
Page 页面
用于创建具有标准布局的页面。
<template>
<div>
<Page :title="pageTitle" :loading="pageLoading">
<template #headerContent>
<div>自定义头部内容</div>
</template>
<template #default>
<div>页面主体内容</div>
</template>
<template #footer>
<div>页面底部内容</div>
</template>
</Page>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Page } from '@cimom/vben-effects-common-ui';
const pageTitle = ref('页面标题');
const pageLoading = ref(false);
</script>
Resize 调整大小
用于创建可调整大小的容器。
<template>
<div>
<Resize :width="300" :height="200" @resize="handleResize">
<div>可调整大小的内容</div>
</Resize>
</div>
</template>
<script setup lang="ts">
import { Resize } from '@cimom/vben-effects-common-ui';
const handleResize = ({ width, height }) => {
console.log('New size:', width, height);
};
</script>
Tippy 提示
用于创建高级提示框的组件。
<template>
<div>
<Tippy content="这是一个提示" placement="top">
<button>鼠标悬停查看提示</button>
</Tippy>
</div>
</template>
<script setup lang="ts">
import { Tippy } from '@cimom/vben-effects-common-ui';
</script>
UI 模板
About 关于页面
提供关于页面的模板。
<template>
<div>
<AboutPage
:version="version"
:buildTime="buildTime"
:dependencies="dependencies"
/>
</div>
</template>
<script setup lang="ts">
import { AboutPage } from '@cimom/vben-effects-common-ui';
const version = 'v1.0.0';
const buildTime = '2025-05-27';
const dependencies = {
vue: '^3.3.0',
vite: '^4.3.0',
typescript: '^5.0.0',
};
</script>
Authentication 认证页面
提供登录、注册、找回密码等认证页面的模板。
<template>
<div>
<LoginForm
:loading="loading"
@login="handleLogin"
@register="handleRegister"
@forgot-password="handleForgotPassword"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { LoginForm } from '@cimom/vben-effects-common-ui';
const loading = ref(false);
const handleLogin = (formData) => {
loading.value = true;
// 处理登录逻辑
setTimeout(() => {
loading.value = false;
}, 1000);
};
const handleRegister = () => {
// 跳转到注册页面
};
const handleForgotPassword = () => {
// 跳转到找回密码页面
};
</script>
Dashboard 仪表盘
提供仪表盘页面的模板。
<template>
<div>
<DashboardAnalysis :loading="loading" :data="dashboardData" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { DashboardAnalysis } from '@cimom/vben-effects-common-ui';
const loading = ref(true);
const dashboardData = ref({
visits: 1024,
sales: 8160,
growth: 12.5,
chartData: [
/* ... */
],
});
// 模拟加载数据
setTimeout(() => {
loading.value = false;
}, 1000);
</script>
Fallback 错误页面
提供 404、403、500 等错误页面的模板。
<template>
<div>
<Page404 @back="goBack" />
<!-- 或者使用其他错误页面 -->
<!-- <Page403 @back="goBack" /> -->
<!-- <Page500 @back="goBack" /> -->
</div>
</template>
<script setup lang="ts">
import { Page404 } from '@cimom/vben-effects-common-ui';
import { useRouter } from 'vue-router';
const router = useRouter();
const goBack = () => {
router.push('/');
};
</script>
继承的核心组件
该包继承了以下核心组件库的所有组件:
@cimom/vben-core-form-ui
表单相关组件,包括输入框、选择器、日期选择器等。
<template>
<div>
<VbenForm :schemas="formSchemas" @submit="handleSubmit" />
</div>
</template>
<script setup lang="ts">
import { VbenForm } from '@cimom/vben-effects-common-ui';
const formSchemas = [
{
field: 'username',
component: 'Input',
label: '用户名',
required: true,
},
{
field: 'password',
component: 'InputPassword',
label: '密码',
required: true,
},
];
const handleSubmit = (values) => {
console.log('Form values:', values);
};
</script>
@cimom/vben-core-popup-ui
弹出层相关组件,包括模态框、抽屉、通知等。
<template>
<div>
<button @click="openModal">打开模态框</button>
</div>
</template>
<script setup lang="ts">
import { useModal } from '@cimom/vben-effects-common-ui';
const { createModal } = useModal();
const openModal = () => {
createModal({
title: '模态框标题',
content: '这是模态框内容',
onOk: () => {
console.log('OK clicked');
},
});
};
</script>
@cimom/vben-core-shadcn-ui
Shadcn UI 组件库,提供了一系列现代化的 UI 组件。
<template>
<div>
<VbenButton variant="primary" @click="handleClick"> 点击按钮 </VbenButton>
<VbenAvatar src="avatar.jpg" alt="User Avatar" />
<VbenTree :data="treeData" @select="handleSelect" />
</div>
</template>
<script setup lang="ts">
import {
VbenButton,
VbenAvatar,
VbenTree,
} from '@cimom/vben-effects-common-ui';
const treeData = [
/* ... */
];
const handleClick = () => {
console.log('Button clicked');
};
const handleSelect = (selectedKeys) => {
console.log('Selected keys:', selectedKeys);
};
</script>
高级用法
组合使用多个组件
<template>
<div>
<Page :title="pageTitle" :loading="pageLoading">
<template #headerContent>
<VbenButton @click="openModal">打开表单</VbenButton>
</template>
<template #default>
<ColPage :span="12">
<template #left>
<JsonViewer :value="jsonData" />
</template>
<template #right>
<Loading :loading="isLoading">
<CountTo :startVal="0" :endVal="2000" :duration="2000" />
</Loading>
</template>
</ColPage>
</template>
</Page>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import {
Page,
ColPage,
JsonViewer,
Loading,
CountTo,
VbenButton,
useModal,
} from '@cimom/vben-effects-common-ui';
const pageTitle = ref('高级示例');
const pageLoading = ref(false);
const isLoading = ref(true);
const jsonData = ref({
/* ... */
});
const { createModal } = useModal();
const openModal = () => {
createModal({
title: '表单示例',
content: h(() => import('./FormComponent.vue')),
width: 600,
});
};
// 模拟加载完成
setTimeout(() => {
isLoading.value = false;
}, 2000);
</script>
创建自定义组件
<!-- MyCustomComponent.vue -->
<template>
<div class="my-custom-component">
<Page :title="title">
<template #default>
<div class="content">
<slot></slot>
</div>
</template>
<template #footer>
<div class="footer">
<VbenButton @click="$emit('cancel')">取消</VbenButton>
<VbenButton variant="primary" @click="$emit('confirm')"
>确认</VbenButton
>
</div>
</template>
</Page>
</div>
</template>
<script setup lang="ts">
import { Page, VbenButton } from '@cimom/vben-effects-common-ui';
defineProps({
title: {
type: String,
default: '自定义组件',
},
});
defineEmits(['cancel', 'confirm']);
</script>
<style scoped>
.my-custom-component {
width: 100%;
height: 100%;
}
.content {
padding: 16px;
}
.footer {
display: flex;
justify-content: flex-end;
gap: 8px;
}
</style>
国际化支持
该包支持国际化,可以与 @cimom/vben-locales
包配合使用。
<template>
<div>
<LoginForm :title="t('auth.loginTitle')" />
</div>
</template>
<script setup lang="ts">
import { LoginForm } from '@cimom/vben-effects-common-ui';
import { useI18n } from '@cimom/vben-locales';
const { t } = useI18n();
</script>
主题定制
该包支持主题定制,可以与 @cimom/vben-effects-hooks
包中的 useDesignTokens
配合使用。
<template>
<div>
<VbenButton :style="{ backgroundColor: primaryColor }">
自定义主题按钮
</VbenButton>
</div>
</template>
<script setup lang="ts">
import { VbenButton } from '@cimom/vben-effects-common-ui';
import { useDesignTokens } from '@cimom/vben-effects-hooks';
const { primaryColor } = useDesignTokens();
</script>
API 参考
ApiSelect 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
api | () => Promise<any[]> | - | 获取选项的 API 函数 |
params | object | {} | 传递给 API 的参数 |
labelField | string | 'label' | 选项标签字段名 |
valueField | string | 'value' | 选项值字段名 |
immediate | boolean | true | 是否立即加载数据 |
Captcha 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
width | number | 120 | 验证码宽度 |
height | number | 40 | 验证码高度 |
codeLength | number | 4 | 验证码长度 |
CountTo 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
startVal | number | 0 | 起始值 |
endVal | number | 0 | 结束值 |
duration | number | 2000 | 动画持续时间(毫秒) |
autoplay | boolean | true | 是否自动播放 |
decimals | number | 0 | 小数位数 |
prefix | string | '' | 前缀 |
suffix | string | '' | 后缀 |
EllipsisText 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
text | string | '' | 要显示的文本 |
len | number | 0 | 截断长度,0 表示不截断 |
tooltip | boolean | true | 是否显示完整文本的提示 |
Loading 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
loading | boolean | false | 是否显示加载状态 |
tip | string | '' | 加载提示文本 |
size | 'small' \| 'default' \| 'large' | 'default' | 加载图标大小 |
absolute | boolean | false | 是否使用绝对定位 |
fullscreen | boolean | false | 是否全屏显示 |
Page 组件
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
title | string | '' | 页面标题 |
loading | boolean | false | 是否显示加载状态 |
content | string | '' | 页面内容 |
contentStyle | object | {} | 内容区域样式 |
contentClass | string | '' | 内容区域类名 |
fixedHeight | boolean | true | 是否固定高度 |
showFooter | boolean | true | 是否显示页脚 |
注意事项
- 该包依赖于多个核心组件包,确保它们已正确安装。
- 部分组件需要配合特定的 CSS 样式使用,确保已导入相应的样式文件。
- 使用
Loading
组件的全屏模式时,需要确保在组件卸载时调用closeFullLoading
方法以避免内存泄漏。 - 使用
ApiSelect
等基于 API 的组件时,需要处理 API 请求可能出现的错误情况。
常见问题
组件样式不生效
确保已正确导入样式文件,可以在入口文件中全局导入:
// main.ts
import '@cimom/vben-effects-common-ui/dist/style.css';
API 组件无法获取数据
检查 API 函数是否正确传递,以及是否处理了异步请求的错误:
<template>
<ApiSelect :api="apiWithErrorHandling" labelField="name" valueField="id" />
</template>
<script setup lang="ts">
import { ApiSelect } from '@cimom/vben-effects-common-ui';
const apiWithErrorHandling = async () => {
try {
const result = await fetch('/api/data');
return await result.json();
} catch (error) {
console.error('API error:', error);
return [];
}
};
</script>
全屏加载无法关闭
确保在组件卸载前关闭全屏加载:
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue';
import { useLoading } from '@cimom/vben-effects-common-ui';
const { openFullLoading, closeFullLoading } = useLoading();
onMounted(() => {
openFullLoading();
});
onBeforeUnmount(() => {
closeFullLoading();
});
</script>