@xnng/ael
v1.1.0
Published
基于 Element Plus 的组件库
Readme
@xnng/ael
基于 Element Plus 的高级组件库,提供了一系列功能强大且易用的组件,大幅简化开发流程,提高开发效率。本组件库专注于企业级应用场景,内置了常用的业务组件,支持暗黑模式,并针对移动端进行了适配优化。
特性
- 🚀 高效开发:提供开箱即用的高级组件,减少重复代码
- 🎨 暗黑模式:内置暗黑模式支持,无需额外配置
- 📱 响应式设计:自动适配桌面端和移动端
- 🔌 按需引入:支持全局注册和按需引入两种方式
- 🧩 TypeScript 支持:完整的类型定义,提供良好的开发体验
- 🔄 与 Element Plus 无缝集成:基于 Element Plus 构建,保持一致的设计风格
安装
# 使用 pnpm 安装
pnpm add @xnng/ael前置依赖
本组件库依赖以下包,请确保它们已安装:
pnpm add vue@^3.3.0 element-plus@^2.4.0 @iconify/vue@^4.1.1 dayjs@^1.11.0使用
全局注册
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import AEL from '@xnng/ael'
import '@xnng/ael/styles'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.use(AEL)
app.mount('#app')按需引入
<script setup lang="ts">
import { ACard, ADialog } from '@xnng/ael'
</script>
<template>
<ACard title="标题">
内容
</ACard>
</template>组件列表
ACard 卡片组件
高级卡片组件,提供标题、自定义样式、边框等功能,支持暗黑模式。
基础用法
<template>
<ACard title="基础卡片">
这是卡片内容
</ACard>
<ACard title="无边框卡片" :showBorder="false">
这是无边框卡片内容
</ACard>
<ACard title="带额外内容的卡片">
<template #title-right>
<el-button type="primary" size="small">操作按钮</el-button>
</template>
这是卡片内容
</ACard>
<ACard title="带额外区域的卡片">
<template #extra>
<div>这是额外区域内容</div>
</template>
这是卡片主要内容
</ACard>
</template>属性
| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | title | 卡片标题 | string | '' | | customClass | 自定义样式类名 | string | '' | | showBorder | 是否显示边框 | boolean | true |
插槽
| 插槽名 | 说明 | | --- | --- | | default | 卡片内容 | | title-right | 标题右侧内容 | | extra | 卡片额外内容区域 |
ADialog 对话框组件
基于 Element Plus 的 Dialog 组件封装,提供了表单验证、自适应布局等增强功能。
基础用法
<template>
<el-button @click="dialogVisible = true">打开对话框</el-button>
<ADialog
v-model:show="dialogVisible"
v-model:modelValue="formData"
title="用户信息"
:column="columns"
@confirm="handleConfirm"
@close="handleClose"
>
<!-- 可选:自定义表单项 -->
<template #username>
<div>自定义用户名输入</div>
</template>
</ADialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ADialog } from '@xnng/ael'
const dialogVisible = ref(false)
const formData = ref({})
// 定义表单列配置
const columns = [
{
prop: 'username',
label: '用户名',
required: true,
editSlot: false, // 使用默认输入框
},
{
prop: 'gender',
label: '性别',
type: 'select',
dicData: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
},
{
prop: 'birthday',
label: '生日',
type: 'date'
}
]
const handleConfirm = ({ done }) => {
console.log('表单数据:', formData.value)
done() // 关闭加载状态
}
const handleClose = () => {
console.log('对话框关闭')
}
</script>属性
| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | show | 是否显示对话框 | boolean | false | | modelValue | 表单数据对象 | object | {} | | title | 对话框标题 | string | '' | | column | 表单列配置 | IColumn[] | [] | | isEdit | 是否为编辑模式 | boolean | false | | isView | 是否为查看模式(禁用所有表单项) | boolean | false | | width | 对话框宽度 | string | '500px' | | top | 对话框距离顶部的距离 | string | '10vh' | | center | 是否居中显示 | boolean | false | | closeOnClickModal | 点击遮罩是否关闭对话框 | boolean | false | | cancelText | 取消按钮文本 | string | '取消' | | confirmText | 确认按钮文本 | string | '确认' |
事件
| 事件名 | 说明 | 回调参数 | | --- | --- | --- | | confirm | 点击确认按钮时触发 | { done: Function } | | close | 对话框关闭时触发 | - | | change | 表单数据变更时触发 | 更新后的表单数据 |
ASearch 搜索组件
高级搜索组件,支持多种搜索条件,可折叠,自适应布局。
基础用法
<template>
<ASearch
v-model="searchForm"
:options="tableOptions"
@search="handleSearch"
@reset="handleReset"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ASearch } from '@xnng/ael'
const searchForm = ref({})
// 表格配置(包含搜索项配置)
const tableOptions = {
column: [
{
prop: 'keyword',
label: '关键词',
search: true, // 显示在搜索区域
searchSort: 1, // 搜索项排序
},
{
prop: 'status',
label: '状态',
type: 'select',
search: true,
searchSort: 2,
dicData: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
},
{
prop: 'dateRange',
label: '日期范围',
type: 'daterange',
search: true,
searchSort: 3
}
],
tableConfig: {
searchLabelWidth: '80px' // 搜索标签宽度
}
}
const handleSearch = ({ done }) => {
console.log('搜索条件:', searchForm.value)
// 执行搜索逻辑
done() // 关闭加载状态
}
const handleReset = ({ done }) => {
console.log('重置搜索')
done() // 关闭加载状态
}
</script>属性
| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | modelValue | 搜索表单数据 | object | {} | | options | 表格配置(包含搜索项配置) | ITableOption | - | | defaultCollapsed | 是否默认折叠 | boolean | true | | customClass | 自定义样式类名 | string | '' | | hideOuterContainer | 是否隐藏外层容器 | boolean | false | | tableRef | 表格实例引用 | any | - |
事件
| 事件名 | 说明 | 回调参数 | | --- | --- | --- | | search | 点击搜索按钮时触发 | { done: Function } | | reset | 点击重置按钮时触发 | { done: Function } | | clear | 清除某个搜索项时触发 | { done: Function } | | update:modelValue | 搜索表单数据更新时触发 | 更新后的表单数据 |
ATable 表格组件
高级表格组件,集成了分页、排序、筛选、编辑、删除等功能,支持树形数据展示。
基础用法
<template>
<ATable
v-model="tableData"
v-model:pagination="pagination"
v-model:selectionList="selectedRows"
:options="tableOptions"
@fetch="fetchData"
@showEdit="handleEdit"
@showAdd="handleAdd"
@delete="handleDelete"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ATable } from '@xnng/ael'
const tableData = ref([])
const selectedRows = ref([])
const pagination = ref({
currentPage: 1,
pageSize: 10,
total: 0
})
// 表格配置
const tableOptions = {
column: [
{
prop: 'id',
label: 'ID',
width: 80
},
{
prop: 'name',
label: '名称',
search: true
},
{
prop: 'status',
label: '状态',
type: 'select',
dicData: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
},
{
prop: 'createTime',
label: '创建时间',
type: 'date'
}
],
tableConfig: {
showAdd: true, // 显示添加按钮
showBtns: true, // 显示操作按钮区域
menu: true, // 显示操作列
editBtn: true, // 显示编辑按钮
delBtn: true, // 显示删除按钮
viewBtn: true, // 显示查看按钮
selection: true, // 显示多选框
align: 'center' // 对齐方式
}
}
const fetchData = ({ done }) => {
// 模拟获取数据
setTimeout(() => {
tableData.value = [
{ id: 1, name: '示例1', status: 1, createTime: '2023-01-01' },
{ id: 2, name: '示例2', status: 0, createTime: '2023-01-02' }
]
pagination.value.total = 2
done() // 关闭加载状态
}, 500)
}
const handleEdit = ({ row, done }) => {
console.log('编辑行:', row)
done() // 关闭加载状态
}
const handleAdd = ({ done }) => {
console.log('添加新行')
done() // 关闭加载状态
}
const handleDelete = ({ row, done }) => {
console.log('删除行:', row)
done() // 关闭加载状态
}
</script>属性
| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | modelValue | 表格数据 | array | [] | | selectionList | 已选择的行数据 | array | [] | | pagination | 分页配置 | object | { currentPage: 1, pageSize: 10, total: 0 } | | options | 表格配置 | ITableOption | - | | defaultExpandAll | 是否默认展开所有行 | boolean | false | | rowKey | 行数据的唯一标识字段 | string | - | | treeProps | 树形表格配置 | object | - |
事件
| 事件名 | 说明 | 回调参数 | | --- | --- | --- | | fetch | 获取表格数据时触发 | { done: Function } | | showEdit | 点击编辑按钮时触发 | { row: object, done: Function } | | showAdd | 点击添加按钮时触发 | { done: Function } | | showView | 点击查看按钮时触发 | { row: object, done: Function } | | delete | 点击删除按钮时触发 | { row: object, done: Function } | | refresh | 刷新表格时触发 | { done: Function } | | actived | 表格行激活时触发 | row: object |
方法
| 方法名 | 说明 | 参数 | | --- | --- | --- | | toggleSelection | 切换行的选中状态 | (row: object, selected: boolean) | | toggleSelectionList | 批量切换行的选中状态 | (rows: array, selected: boolean) | | selectionClear | 清空选中状态 | - | | setLoading | 设置表格加载状态 | (loading: boolean) |
AIcon 图标组件
基于 Iconify 的图标组件,支持 Element Plus 图标和其他流行图标集。
基础用法
<template>
<AIcon icon="ep:edit" />
<AIcon icon="ep:delete" color="red" />
<AIcon icon="ep:search" :size="24" />
</template>属性
| 属性名 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | icon | 图标名称 | string | - | | color | 图标颜色 | string | - | | size | 图标大小 | number | string | - |
类型定义
组件库提供了完整的 TypeScript 类型定义,便于开发时获得良好的类型提示和代码补全。以下是主要类型定义的详细说明:
回调函数类型
DoneCallback
用于处理异步操作完成后的回调函数类型。
export interface DoneCallback {
row?: any; // 可选的行数据
done: () => void; // 完成回调函数,用于关闭加载状态等
}RowCallback
扩展自 DoneCallback,包含必须的行数据。
export interface RowCallback extends DoneCallback {
row: any; // 必须的行数据
}数据字典类型
IDicData
用于下拉选择、单选按钮等组件的数据项定义。
export interface IDicData {
label: string; // 显示的标签文本
value: boolean | number | string; // 对应的值
tagType?: 'danger' | 'info' | 'primary' | 'success' | 'warning'; // 标签类型(用于渲染不同颜色)
}列配置类型
IColumn
表格列、表单项、搜索项的统一配置接口,非常核心的类型定义。
export interface IColumn {
// 基本属性
label: string; // 字段名称(显示的标签)
prop: string; // 字段属性(对应数据的键名)
virtual?: boolean; // 是否为虚拟列,默认 false
tip?: string; // 提示文案
placeholder?: string; // 搜索框提示文案
suffix?: string; // 单位显示
// 类型相关
type?: 'date' | 'daterange' | 'datetime' | 'datetimerange' | 'img' | 'radio' | 'select' | 'text' | 'textarea'; // 字段类型
editType?: 'date' | 'daterange' | 'datetime' | 'datetimerange' | 'radio' | 'select' | 'text' | 'textarea'; // 编辑字段类型
tableType?: 'date' | 'daterange' | 'datetime' | 'datetimerange' | 'radio' | 'select' | 'text'; // 表格字段类型
// 搜索相关
search?: boolean; // 是否可搜索
searchSort?: number; // 搜索字段排序
searchLabelWidth?: number; // 搜索label宽度,单位 px
searchWidth?: number; // 搜索内容宽度,单位 px
searchLable?: string; // 搜索框 label(注意这里的拼写是 Lable 而不是 Label)
searchDisabled?: boolean; // 搜索时是否禁用
searchSlot?: boolean; // 搜索插槽
// 编辑相关
editSort?: number; // 编辑字段排序
editLabel?: string; // 编辑框label
editLabelWidth?: number; // 编辑框label宽度
editDisplay?: boolean; // 编辑时是否显示
editDisabled?: boolean; // 编辑时是否禁用
editSlot?: boolean; // 编辑插槽
editLabelSlot?: boolean; // 是否自定义 edit label
span?: number; // 编辑框栅格宽度
// 表格相关
width?: number; // 字段表格宽度
align?: 'center' | 'left' | 'right'; // 对齐方式
tableDisplay?: boolean; // 表格中是否显示
isTableColumn?: boolean; // 是否是表格中的字段
slot?: boolean; // 表格显示插槽
showOverflowTooltip?: boolean; // 是否显示省略
showCopyBtn?: boolean; // 是否显示复制按钮
// 表单验证相关
required?: boolean; // 编辑框是否必填
validate?: RegExp; // 表单校验规则(正则表达式)
validateTip?: string; // 表单校验错误提示
rules?: (row: any, formRef: Ref<FormInstance | null>) => FormItemRule[]; // 表单校验规则(函数形式)
// 选择器相关
dicData?: IDicData[]; // select/radio 类型的字段数据
multiple?: boolean; // 是否多选
radioMinWidth?: number; // 单选按钮组每项最小宽度
// 日期相关
valueFormat?: string; // 时间格式
disabledDate?: (time: Date) => boolean; // 日期禁用函数
// 文本相关
maxlength?: number; // 文本框输入长度限制
textAreaConfig?: { // textarea 配置
maxRows?: number; // 最大行数
minRows?: number; // 最小行数
};
// 其他
size?: 'default' | 'large' | 'small'; // 组件大小
tag?: boolean; // 是否显示tag
formatter?: (value: any) => string; // 数据格式化
imgStyle?: string; // 图片样式,当 type 为 img 时生效
clearable?: boolean; // 是否显示清除按钮
}表格配置类型
ITableOption
表格组件的配置选项接口,包含列定义和表格行为配置。
export interface ITableOption {
column: IColumn[]; // 列配置数组
tableConfig?: { // 表格配置
// 按钮控制
addBtn?: boolean; // 是否显示添加按钮
addBtnPermission?: string; // 添加按钮权限值
editBtn?: boolean; // 是否显示编辑按钮
editBtnPermission?: string; // 编辑按钮权限值
delBtn?: boolean; // 是否显示删除按钮
delBtnPermission?: string; // 删除按钮权限值
viewBtn?: boolean; // 是否显示查看按钮
exportBtn?: boolean; // 是否显示导出按钮
showBtns?: boolean; // 是否显示表格上方的按钮组
// 表格样式
align: 'center' | 'left' | 'right'; // 对齐方式
border?: boolean; // 是否显示表格边框
size?: 'default' | 'large' | 'small'; // 尺寸
stripe?: boolean; // 是否显示斑马纹
// 序号列
index?: boolean; // 是否显示序号
indexFixed?: boolean; // 是否固定序号
indexLabel?: string; // 序号字段名称
indexWidth?: number; // 序号字段宽度
// 操作列
menu?: boolean; // 是否显示操作栏
menuWidth?: number; // 操作栏宽度
// 选择功能
selection?: boolean; // 是否展示多选
// 分页相关
showPagination?: boolean; // 是否显示分页
paginationConfig?: { // 分页配置
layout?: string; // 组件布局 'total, sizes, prev, pager, next, jumper'
pageSizes?: number[]; // 每页显示个数选择器的选项设置 [10, 20, 30, 40, 50]
small?: boolean; // 是否使用小型分页样式
};
// 搜索相关
searchLabelWidth?: number; // 搜索label宽度
};
}使用示例
以下是如何在代码中使用这些类型的示例:
import { IColumn, ITableOption } from '@xnng/ael';
// 定义列配置
const columns: IColumn[] = [
{
prop: 'id',
label: 'ID',
width: 80
},
{
prop: 'name',
label: '名称',
search: true,
required: true,
validateTip: '请输入名称'
},
{
prop: 'status',
label: '状态',
type: 'select',
dicData: [
{ label: '启用', value: 1, tagType: 'success' },
{ label: '禁用', value: 0, tagType: 'danger' }
]
}
];
// 定义表格配置
const tableOptions: ITableOption = {
column: columns,
tableConfig: {
align: 'center',
border: true,
stripe: true,
showBtns: true,
menu: true,
editBtn: true,
delBtn: true,
viewBtn: true,
selection: true
}
};依赖
- Vue 3.3+
- Element Plus 2.4+
- @iconify/vue 4.1+
- dayjs 1.11+
浏览器兼容性
- 支持所有现代浏览器
- 不支持 IE 11
贡献指南
欢迎提交 Issue 或 Pull Request 来帮助改进这个组件库。
