@hanvzur/aor-ui
aor-ui
一个基于 Vue 3 和 Element Plus 的自定义组件库,在 Element Plus 之上做轻量二次封装,统一视觉规范、简化常用 API。视觉风格为年轻活力的渐变紫蓝主题(大圆角、悬浮微动效),详见 dist/index.css 中的 CSS 变量。
特性
- 基于 Vue 3 + TypeScript 开发,类型声明随包发布
withInstall双注册模式:既支持app.use()全局安装,也支持按需引入单个组件- ESM + CJS 双格式产物,
exports规范入口,Vite / Webpack / Node 通用 vue与element-plus走 peerDependencies,不打入产物,零冗余依赖- 面向企业级中后台场景的 Schema 驱动组件:动态表单、搜索表单、配置化表格等
- vitest 单元测试 + ESLint + Prettier 质量链
安装
npm i @hanvzur/aor-ui
要求使用方环境已安装 vue@^3.5 与 element-plus@^2.13(peerDependencies,不会自动安装)。
快速开始
完整引入(组件 + 样式):
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import AorUI from '@hanvzur/aor-ui'
import '@hanvzur/aor-ui/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.use(AorUI) // 全局注册全部 Ar* 组件 + DemoBlock
app.mount('#app')
按需引入
手动引入组件时样式仍需全局引入一次:
import { ArButton, ArCard, ArRadioGroup, ArForm, ArTable } from '@hanvzur/aor-ui'
import '@hanvzur/aor-ui/dist/index.css'
配合 unplugin-vue-components 可实现模板免 import:
// vite.config.ts
import Components from 'unplugin-vue-components/vite'
export default {
plugins: [
Components({
resolvers: [
(name) => {
if (name.startsWith('Ar')) return { name, from: '@hanvzur/aor-ui' }
},
],
}),
],
}
组件
ArButton 按钮
在 el-button 基础上统一圆角与字重。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| type | 同 el-button type | 'primary' |
按钮类型 |
| size | 同 el-button size | 'default' |
按钮尺寸 |
| disabled | boolean | false |
禁用 |
| loading | boolean | false |
加载中 |
<ArButton>主要按钮</ArButton>
<ArButton type="success">成功按钮</ArButton>
<ArButton type="danger" size="small">危险按钮</ArButton>
<ArButton disabled>禁用按钮</ArButton>
ArCard 卡片
在 el-card 基础上提供标题头部与圆角样式。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| title | string | — | 卡片标题(渲染到 header) |
| shadow | 'always' | 'hover' | 'never' |
'never' |
阴影时机 |
| bordered | boolean | true |
边框 |
| showAction | boolean | false |
是否显示头部操作区 |
<ArCard title="卡片标题" show-action>
<p>卡片内容插槽</p>
</ArCard>
ArRadioGroup 单选组
通过 options 驱动的单选组,替代手动罗列 el-radio。
| Prop | 类型 | 说明 |
|---|---|---|
| modelValue | string | number | boolean | 选中值(v-model) |
| options | { label: string; value: string | number | boolean }[] |
选项列表 |
<ArRadioGroup v-model="value" :options="[{ label: '北京', value: 'beijing' }]" />
ArForm Schema 动态表单
一个 JSON 配置驱动整个表单:字段渲染、栅格布局、联动显隐、联动禁用、校验规则全部收敛到 fields 里。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | Record<string, unknown> |
— | 表单数据对象(v-model) |
| fields | ArFormField[] |
— | 字段配置 |
| labelWidth | string | number | '90px' |
标签宽度 |
| labelPosition | 'left' | 'right' | 'top' |
'right' |
标签位置 |
| gutter | number | 16 |
栅格间隔 |
| defaultSpan | number | 24 |
未指定 span 时的栅格宽度 |
| disabled | boolean | false |
整体禁用 |
ArFormField 核心配置:
| 字段 | 类型 | 说明 |
|---|---|---|
| prop / label | string | 字段名(校验路径)/ 标签文案 |
| type | 'input' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'switch' | 'date' | 'datetime' | 'number' |
渲染类型,默认 input |
| required | boolean | 快捷必填校验(input 走 blur,其余走 change) |
| rules | FormItemRule[] |
追加自定义校验规则 |
| options | ArFormOption[] |
select / radio / checkbox 选项 |
| visible | (model) => boolean |
联动显隐 |
| disabled | boolean | (model) => boolean |
联动禁用 |
| span / tip / props / placeholder | — | 栅格宽度 / 说明文字 / 透传内部 el-* 组件 |
插槽:与字段 prop 同名的插槽可整字段自定义渲染;footer 插槽自定义底部按钮。
实例方法(ref):validate() / validateField() / resetFields() / clearValidate() / getFieldsValue()。
<ArForm
ref="formRef"
v-model="form"
:fields="[
{ prop: 'name', label: '姓名', required: true },
{ prop: 'city', label: '城市', type: 'select', options: cityOptions },
{ prop: 'extra', label: '附加信息', visible: (m) => m.vip },
{ prop: 'remark', label: '备注', type: 'textarea', span: 24 },
]"
>
<template #footer>
<el-button type="primary" @click="formRef.validate()">提交</el-button>
</template>
</ArForm>
ArSearchForm 搜索表单
基于 ArForm,内置「查询 / 重置」按钮与初始条件快照,列表页搜索区标配。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | Record<string, unknown> |
— | 查询条件对象(v-model) |
| fields | ArFormField[] |
— | 查询字段配置(同 ArForm) |
| labelWidth | string | number | 'auto' |
标签宽度 |
| defaultSpan | number | 8 |
默认一行 3 个字段 |
事件:search(value) 点击查询 / reset() 点击重置(自动还原进入页面时的条件)。插槽:actions 追加按钮,字段插槽同 ArForm。
<ArSearchForm v-model="query" :fields="queryFields" @search="loadList" @reset="loadList" />
ArTable 配置化表格
columns 驱动的 el-table,内置分页器与多选支持。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| data | ArTableRow[] |
— | 表格数据 |
| columns | ArTableColumn[] |
— | 列配置 |
| loading | boolean | false |
加载态 |
| showPager | boolean | false |
是否显示分页器 |
| currentPage / pageSize / total | number | — | 分页(currentPage 支持 v-model) |
| pageSizes | number[] | [10, 20, 50, 100] |
每页条数选项 |
| border / emptyText / showOverflowTooltip | — | — | 透传 el-table |
ArTableColumn:type(index / selection)、prop、label、width、minWidth、fixed、align、formatter、slot(声明后由同名插槽渲染该列单元格)。
事件:page-change({ page, pageSize })、update:currentPage、selection-change(rows)。
<ArTable
v-model:currentPage="page"
:data="list"
:columns="[
{ type: 'selection' },
{ prop: 'name', label: '姓名' },
{ prop: 'status', label: '状态', slot: 'status' },
{ prop: 'createdAt', label: '创建时间', formatter: (row) => dayjs(row.createdAt).format('YYYY-MM-DD') },
]"
show-pager
:total="total"
@page-change="loadList"
>
<template #status="{ row }">
<el-tag>{{ row.status }}</el-tag>
</template>
</ArTable>
ArDialog 弹窗
内置确定 / 取消底部按钮与防重复提交 loading 的二次封装弹窗。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | boolean | — | 是否可见(v-model) |
| title | string | '' |
标题 |
| width | string | number | '520px' |
宽度 |
| confirmText / cancelText | string | '确定' / '取消' |
按钮文案 |
| showFooter | boolean | true |
使用 footer 插槽时自动隐藏默认按钮 |
| confirmLoading | boolean | false |
确定按钮 loading(异步提交防重复点击) |
| closeOnClickModal | boolean | false |
点击遮罩关闭 |
| draggable | boolean | false |
可拖拽 |
事件:confirm() 点击确定(不自动关闭,由使用方决定何时关)、cancel() 点击取消(自动关闭)。
<ArDialog v-model="visible" title="创建成员" :confirm-loading="submitting" @confirm="handleSubmit">
<ArForm v-model="form" :fields="fields" />
</ArDialog>
ArDescriptions 描述列表
配置驱动的详情展示,支持 formatter 与空值占位。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| data | Record<string, unknown> |
{} |
数据对象 |
| items | ArDescriptionsItem[] |
— | 展示项配置 |
| title | string | '' |
标题 |
| column | number | 2 |
每行列数 |
| border | boolean | true |
边框 |
ArDescriptionsItem:label、prop、formatter(data) 自定义格式化,空值统一显示 —。
<ArDescriptions
:data="detail"
:items="[
{ label: '姓名', prop: 'name' },
{ label: '入职时间', prop: 'joinedAt', formatter: (d) => d.joinedAt.slice(0, 10) },
]"
/>
ArUpload 上传
内置大小 / 数量校验与图片墙触发器的上传封装。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | UploadUserFile[] |
[] |
文件列表(v-model) |
| action | string | — | 上传地址 |
| accept | string | '' |
接受的文件类型 |
| limit | number | 5 |
最大上传数量 |
| listType | 'text' | 'picture' | 'picture-card' |
'picture-card' |
列表样式 |
| maxSize | number | 0 |
单文件大小上限(MB),0 不限制 |
| autoUpload | boolean | true |
自动上传 |
| tip | string | '' |
提示文案 |
<ArUpload v-model="fileList" action="/api/upload" accept="image/*" :max-size="2" tip="单张不超过 2MB" />
DemoBlock 演示块
组件文档站用:上方渲染 demo 插槽,下方可折叠展示代码(配合 v-highlight 指令高亮,由使用方自行注册)。
<DemoBlock :code="codeString">
<template #demo>
<ArButton>示例</ArButton>
</template>
</DemoBlock>
产物规范
发布包只含 dist/(files 白名单),通过 exports 字段区分入口:
| 格式 | 文件 | 场景 |
|---|---|---|
| ESM | dist/index.mjs |
Vite / Webpack / Node ESM |
| CJS | dist/index.cjs |
Node require / SSR |
| 类型 | dist/types/index.d.ts |
TypeScript 提示 |
| 样式 | dist/index.css |
使用方需自行引入 |
本地开发
npm run dev # 组件演示页
npm run lint # ESLint 检查
npm run test # vitest 单元测试
npm run build:lib # 构建产物到 dist/(ESM + CJS + 类型)
npm publish # 发布(prepublishOnly 会先自动构建)
License
MIT
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.1 | ^3.5.24 | MIT | |
| 1.0.0 | ^3.5.24 | MIT |