xdc-ui-lib
v2.2.0
Published
常用组件库
Maintainers
Readme
xdc-ui-lib
Vue 3 组件库,包含常用的业务组件,基于 ant-design-vue。
环境要求
- Node.js:建议 18+
- Vue:3.x
- ant-design-vue:4.x
安装
npm install xdc-ui-lib ant-design-vue快速开始
import { createApp } from 'vue'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'
import XdcUiLib from 'xdc-ui-lib'
import 'xdc-ui-lib/xdc-ui-lib.css'
const app = createApp(App)
app.use(Antd)
app.use(XdcUiLib)
app.mount('#app')发布/构建说明(维护者)
- 构建:
pnpm run build - 发布:进入构建产物目录
xdc-ui-lib/后执行npm publish
常见发布报错:
- 403 Forbidden - You cannot publish over the previously published versions
- 说明:尝试重复发布同一个版本号(例如
2.1.9已经发布过) - 处理:修改版本号后再发布(建议使用
npm version patch|minor|major递增版本)
- 说明:尝试重复发布同一个版本号(例如
组件列表(目录)
CategorySearch 分类搜索组件
一个功能强大的分类搜索组件,支持多种筛选类型和列设置功能。
基本用法
<template>
<CategorySearch
:loading="loading"
:filter-types="filterTypes"
:columns="columns"
@search="handleSearch"
/>
</template>
<script setup>
import { CategorySearch } from 'xdc-ui-lib';
const filterTypes = [
{
id: 'name',
label: '名称',
type: 'input',
placeholder: '请输入名称'
},
{
id: 'status',
label: '状态',
type: 'select',
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 }
]
}
];
const columns = [
{ title: '名称', dataIndex: 'name' },
{ title: '状态', dataIndex: 'status' }
];
</script>支持的筛选类型
input: 文本输入textarea: 多行文本select: 下拉选择cascader: 级联选择treeSelect: 树形选择checkbox: 多选框radio: 单选框date: 日期选择datetime: 日期时间选择dateRange: 日期范围datetimeRange: 日期时间范围time: 时间选择numberRange: 数字范围rate: 评分slider: 滑块switch: 开关slot: 自定义插槽
高级功能
<template>
<CategorySearch
type="form"
:filter-types="filterTypes"
:form-layout="'vertical'"
:form-span="8"
v-model:filter-value="searchParams"
@search="handleSearch"
/>
</template><template>
<CategorySearch
:show-setting-columns="true"
:columns="columns"
:disabled-columns="['id', 'name']"
@columnsChange="handleColumnsChange"
/>
</template><template>
<CategorySearch :filter-types="filterTypes">
<template #filter-slots="{ filter, filterTemp, confirm }">
<CustomComponent
v-if="filter.id === 'customField'"
v-model:value="filterTemp[filter.id]"
@change="confirm"
/>
</template>
</CategorySearch>
</template>const filterTypes = [
{
id: 'status',
type: 'select',
label: $t('table.probe') + $t('table.Blank') + $t('table.Status'),
options: [...]
}
];Props
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| type | 组件模式:input 为“输入框 + tag + 下拉面板”;form 为“表单平铺模式” | 'input' \| 'form' | 'input' |
| filterValue | 当前筛选值(用于回显/受控)。Input 模式下会转换为 tag;Form 模式下会同步到表单模型 | Record<string, any> | {} |
| loading | 加载态;为 true 时会阻止搜索/刷新等操作 | boolean | 必传 |
| filterTypes | 筛选项配置数组(决定可选条件、控件类型、options 等) | any[] | 必传 |
| placeholder | Input 模式下输入框占位文案 | string | '点击选择搜索条件' |
| storageKey | 本地缓存 key;不传则自动基于 location + 配置生成,确保同页不同配置不冲突 | string | '' |
| hideRefresh | 是否隐藏刷新/搜索按钮 | boolean | false |
| showSwitch | 是否显示“切换”按钮(点击会 emit switch) | boolean | false |
| showSave | 是否显示“保存”按钮(将当前筛选条件写入缓存) | boolean | false |
| showSettingColumns | 是否显示“列设置”入口(作用于 columns) | boolean | true |
| columns | 表格列配置(用于列设置面板的显隐/排序/固定) | any[] | [] |
| disabledColumns | 列设置中禁用的列(不可隐藏/不可拖拽/不可固定),匹配 dataIndex/key | string[] | ['id','name'] |
| isDefaultSearch | 初始化时是否读取缓存并自动触发一次搜索 | boolean | true |
| formLayout | Form 模式布局(grid 时内部用 CSS 变量控制列数) | 'horizontal' \| 'vertical' \| 'inline' \| 'grid' | 'grid' |
| formSpan | Form 模式 grid 布局下列数(--form-columns) | number | 4 |
| labelCol | AntD Form 的 labelCol(仅 form 模式相关) | any | - |
| wrapperCol | AntD Form 的 wrapperCol(仅 form 模式相关) | any | - |
| labelBorder | grid 表单是否显示 label 边框样式(.grid-form) | boolean | false |
| colon | label 是否显示冒号(AntD Form colon) | boolean | false |
| collapsedCount | Form 模式折叠时展示前 N 个筛选项:传了才启用折叠逻辑(支持 0) | number | undefined |
| defaultCollapsed | Form 模式默认是否折叠(仅在启用折叠逻辑时生效) | boolean | true |
存储键生成规则
组件会根据以下规则生成存储键:
- 如果提供了
storageKey:直接使用提供的值 - 如果没有提供
storageKey:自动生成基于页面路径和配置的唯一键
当没有提供 storageKey 时,组件会自动生成一个基于以下信息的唯一存储键:
- 当前页面路径
- 筛选类型配置
- 表格列配置
生成的键格式为:category_search_auto_${hash}
这样可以确保每个页面和配置组合都有唯一的存储键,避免数据冲突。
<template>
<!-- 使用路由名称作为存储键 -->
<CategorySearch
:storage-key="`search-${$route.name}`"
:loading="loading"
:filter-types="filterTypes"
@search="handleSearch"
/>
</template><template>
<CategorySearch
storage-key="user-list-search"
:loading="loading"
:filter-types="filterTypes"
@search="handleSearch"
/>
</template><template>
<!-- 不提供 storageKey,自动生成 -->
<CategorySearch
:loading="loading"
:filter-types="filterTypes"
:columns="columns"
@search="handleSearch"
/>
</template>Events
| 事件名 | 说明 | 回调参数 | |--------|------|----------| | search | 搜索事件 | (params: object) | | switch | 切换事件 | (filters: array) | | clear | 清空事件 | - | | reset | 重置事件 | - | | columnsChange | 列变化事件 | (columns: array) | | update:columns | 列更新事件 | (columns: array) | | update:filterValue | 筛选值更新事件 | (value: object) |
SearchPanel 搜索面板组件
SearchPanel 是一个“搜索条件构建器”组件,支持两种模式:
type="input":输入框 + tag 的交互式条件选择(带下拉面板)type="form":表单平铺模式(可折叠),更适合复杂筛选场景
同时内置:
- 筛选条件本地缓存(基于
storageKey) - 条件保存/恢复
- 筛选项显示/隐藏/排序(“列设置”面板,但作用对象是 filterTypes)
- 国际化(使用内置
useI18n的t('searchPanel.xxx'))
基本用法(Input 模式)
<template>
<SearchPanel
:loading="loading"
:filter-types="filterTypes"
v-model:filter-value="params"
@search="onSearch"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { SearchPanel } from 'xdc-ui-lib'
const loading = ref(false)
const params = ref<Record<string, any>>({})
const filterTypes = [
{ id: 'name', label: '名称', type: 'input', placeholder: '请输入名称' },
{
id: 'status',
label: '状态',
type: 'select',
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 },
],
},
]
function onSearch(payload: Record<string, any>) {
console.log('search:', payload)
}
</script>基本用法(Form 模式)
<template>
<SearchPanel
type="form"
:loading="loading"
:filter-types="filterTypes"
:form-layout="'grid'"
:form-span="4"
:collapsed-count="6"
v-model:filter-value="params"
@search="onSearch"
/>
</template>支持的筛选类型(filterTypes[].type)
与 CategorySearch 基本一致,另外支持更多日期 picker:
input/textareaselect/cascader/treeSelectcheckbox/radiodate/datetime/month/week/quarter/yeartimedateRange/datetimeRangenumberRangerate/slider/switchslot
Props
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| type | 组件模式:input 为“输入框 + tag + 下拉面板”;form 为“表单平铺模式” | 'input' \| 'form' | 'input' |
| loading | 外部 loading 状态;为 true 时会阻止搜索/刷新等操作 | boolean | false |
| filterTypes | 筛选项配置数组(决定可选条件、控件类型、options 等) | any[] | 必传 |
| optionDict | 统一下拉数据字典:key 与 filterTypes[i].dictKey/optionKey/id 对应;优先级高于 filterTypes[i].options/treeData | Record<string, any[]> | {} |
| filterValue | 当前筛选值(用于回显/受控) | Record<string, any> | {} |
| placeholder | Input 模式占位文案 | string | '点击选择搜索条件' |
| storageKey | 本地缓存 key;不传时默认使用 search-panel:${pathname}${search} | string | '' |
| hideRefresh | 是否隐藏刷新/搜索按钮 | boolean | false |
| showSwitch | 是否显示“切换”按钮(点击会 emit switch) | boolean | false |
| showSave | 是否显示“保存”按钮(将当前筛选条件写入缓存) | boolean | false |
| showSettingColumns | 是否显示“筛选项显示设置”按钮(作用对象为 filterTypes) | boolean | true |
| disabledFilterTypes | 不允许隐藏的筛选项 id 列表(例如必须展示的条件) | string[] | [] |
| isDefaultSearch | 初始化时是否读取缓存并自动触发一次搜索 | boolean | true |
| formLayout | Form 模式布局:horizontal/vertical/inline/grid | 'horizontal' \| 'vertical' \| 'inline' \| 'grid' | 'grid' |
| formSpan | Form 模式 grid 布局下列数(CSS 变量:--form-columns) | number | 4 |
| labelCol | AntD Form 的 labelCol(horizontal/grid 相关) | any | - |
| wrapperCol | AntD Form 的 wrapperCol(horizontal/grid 相关) | any | - |
| labelBorder | Form 模式是否显示 label 边框样式(grid-form) | boolean | false |
| colon | Form 模式 label 是否显示冒号(AntD Form colon) | boolean | false |
| collapsedCount | Form 模式折叠时展示前 N 个筛选项:传了才启用折叠逻辑(支持 0) | number | undefined |
| defaultCollapsed | Form 模式默认是否折叠(仅在启用折叠逻辑时生效) | boolean | true |
| searchDisabled | Form 模式“查询”按钮禁用 | boolean | false |
| clearHidden | Form 模式是否隐藏“清除”按钮 | boolean | false |
| clearDisabled | Form 模式“清除”按钮禁用 | boolean | false |
| columns | 兼容旧入参(已不再使用) | any[] | [] |
| disabledColumns | 兼容旧入参(已不再使用) | string[] | [] |
说明:组件内部还存在
collapsible默认值,但当前 props 定义里未显式声明(属于历史字段/可忽略)。
Events
| 事件名 | 说明 | 回调参数 |
|------|------|----------|
| search | 点击刷新/确认/表单搜索时触发(会扁平化部分日期结构) | (params: Record<string, any>) |
| switch | 点击切换按钮触发 | (filters: any[]) |
| clear | 调用 reset/清空时触发 | () |
| reset | (当前代码未 emit reset,仅保留事件名;如需可补) | () |
| columnsChange | (历史事件名:当前主要用于 filterTypes 显示设置,不建议依赖) | (cols: any[]) |
| update:columns | (历史 v-model:当前主要用于 filterTypes 显示设置,不建议依赖) | (cols: any[]) |
| update:filterValue | v-model 回写,用于回显/受控 | (value: any) |
Slots
| 插槽名 | 说明 | 参数 |
|------|------|------|
| icon | Input 模式右侧自定义操作按钮区域(点击事件需自行处理) | - |
| filter-slots | 当 filterTypes[].type === 'slot' 时渲染 | { filter, filterTemp, confirm } |
方法(Expose)
通过 ref 可调用:
reset():清空条件并触发一次 searchsearch():触发一次 search(内部有 throttle 800ms)
ColumnSetting 表格列设置组件
用于表格列的显示/隐藏、拖拽排序、左右固定,并支持 localStorage 持久化。
适用场景
- 表格列“显隐/排序/固定(左/右)”需要给用户自定义
- 需要把列配置持久化到 localStorage(同页面刷新仍保持)
- 需要禁用某些关键列(不可隐藏/不可拖拽)
基本用法
<template>
<ColumnSetting
v-model:columns="columnSetting"
storageKey="user-list-columns"
:disabledColumns="['id']"
>
<template #trigger>
<a-button>列设置</a-button>
</template>
</ColumnSetting>
<a-table :columns="columnSetting" :data-source="dataSource" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ColumnSetting } from 'xdc-ui-lib'
const columns = [
{ title: 'ID', dataIndex: 'id', key: 'id' },
{ title: '名称', dataIndex: 'name', key: 'name' },
{ title: '状态', dataIndex: 'status', key: 'status' },
]
const dataSource = []
const columnSetting = ref([])
</script>与其他组件的关系
ColumnSetting 已解耦,可 独立使用(不依赖 CategorySearch / SearchPanel 等组件)。
- 只要提供
v-model:columns绑定的列配置,即可完成列的显隐/排序/固定与持久化。 - 如需在其他组件中集成(例如放在表格工具栏里),直接按本章「基本用法(与 antd Table 配合)」接入即可。
Props
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| columns | 原始列配置(列设置作用对象)。列项建议包含 title/dataIndex/key,以便稳定识别与排序 | ColumnSettingColumn[] | 必传 |
| storageKey | localStorage 存储 key;不传则默认使用 column-setting:${pathname}${search}(同页面不同 query 会区分) | string | '' |
| disabledColumns | 禁用列 id(匹配 dataIndex/key):不可隐藏、不可拖拽、不可固定 | string[] | [] |
| hiddenColumns | 完全隐藏且不可操作的列 id(匹配 dataIndex/key):不会在面板出现 | string[] | ['index','action'] |
| size | 表格密度(可选);传了会参与缓存,并通过 v-model:size 同步给外部 | 'small' \| 'middle' \| 'large' | undefined |
| needConfirm | 是否需要点击“确认”才真正对外生效:
false:用户操作即时 emit(默认)true:用户操作仅在弹层内暂存,点击确认才 emit & 写缓存;关闭/取消会丢弃未确认修改 |boolean|false|
说明:
ColumnSetting通过v-model:columns输出 可见列(已过滤checked=false且去掉checked字段)。如果你需要拿到“包含 checked/fixed/排序”的全量结构,建议在业务侧用useColumnSettinghook。
Events
| 事件名 | 说明 | 回调参数 | |------|------|----------| | update:modelValue | 列设置变更(全量) | (cols: array) | | update:visibleColumns | 可见列变更(过滤 checked=false) | (cols: array) | | change | 同 update:modelValue | (cols: array) | | reset | 点击重置触发 | - |
BaseTable 表格增强组件
BaseTable 是对 ant-design-vue 的 a-table 做的“增强但不打扰”的封装:
- 不重复声明 a-table 的全部 props/emits:通过
useAttrs()全量透传 - 动态转发所有 a-table 插槽:不影响你使用官方的 slots
- 提供可选工具条(标题/操作区)
- 内置列设置按钮(复用
ColumnSetting),以及刷新/密度(size)切换 - loading 兼容增强、error 空态兜底
基本用法
<template>
<BaseTable
:columns="columns"
:data-source="dataSource"
:pagination="pagination"
@change="onChange"
/>
</template>
<script setup lang="ts">
import { BaseTable } from 'xdc-ui-lib'
const columns = [
{ title: 'ID', dataIndex: 'id', key: 'id' },
{ title: '名称', dataIndex: 'name', key: 'name' },
]
const dataSource = []
const pagination = { current: 1, pageSize: 10, total: 0 }
function onChange(...args: any[]) {
console.log('table change', args)
}
</script>工具条(title + 操作)
<BaseTable title="用户列表" :columns="columns" :data-source="dataSource" @refresh="fetchList" />列设置(ColumnSetting 集成)
BaseTable 会在工具条右侧渲染列设置入口(前提:你传入了 columns)。
你可以直接把 ColumnSetting 的相关 props 当作 attribute 传给 BaseTable:
<BaseTable
title="用户列表"
:columns="columns"
:data-source="dataSource"
storageKey="user-list-columns"
:disabledColumns="['id']"
/>Props(BaseTable 自身声明的)
说明:除下表外,
a-table的所有 props/事件都可以直接v-bind/监听传入。
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| title | 工具条标题(默认展示在左侧) | string | - |
| toolbar | 是否展示工具条;不传时按“title/slot/toolbarActions 是否存在”自动判断 | boolean | undefined |
| toolbarActions | 是否显示右侧默认操作区(列设置/刷新/密度) | boolean | true |
| error | 错误信息(string 或 Error),用于空态兜底 | string \| Error \| null | null |
| loading | loading 增强:boolean / {spinning, tip} / AntD 原生 loading 对象 | boolean \| {spinning?: boolean; tip?: string} \| Record<string, any> | undefined |
| defaultSize | 默认表格密度(仅当外部未传 size 时生效) | 'small' \| 'middle' \| 'large' | 'middle' |
| showRefresh | 是否显示刷新按钮(工具条右侧) | boolean | true |
| showDensity | 是否显示密度切换(外部传了 size 时会自动隐藏) | boolean | true |
| autoHeight | 是否自动计算 scroll.y(不覆盖外部显式传入的 scroll.y) | boolean | true |
| autoHeightOffset | 自动高度模式下额外扣减高度(px) | number | 40 |
| autoHeightMinY | 自动高度模式下 scroll.y 最小值(px) | number | 10 |
Events(BaseTable 自身声明的)
| 事件名 | 说明 | 回调参数 |
|------|------|----------|
| refresh | 点击刷新按钮触发 | () |
| update:size | 点击密度切换触发;若外部未受控,会同时更新内部 size | (size: 'small' \| 'middle' \| 'large') |
Slots
| 插槽名 | 说明 | |------|------| | toolbar-left | 覆盖工具条左侧区域(默认显示 title) | | toolbar-right | 覆盖工具条右侧区域(默认显示 toolbarActions 区) | | toolbar-extra | 在默认 toolbarActions 区后追加内容 |
除以上 3 个工具条插槽外,所有 a-table 的插槽都会被动态透传(例如
bodyCell、headerCell、expandedRowRender、emptyText等)。
默认行为(仅在外部未传时生效)
rowKey默认为'id'scroll默认为{ x: 'max-content' }locale.emptyText默认为'暂无数据'(若传入 error 且外部未提供 empty slot/locale.emptyText,则显示 error)
BaseForm 动态表单组件
一个功能强大的动态表单组件,支持多种表单元素类型、布局方式和自定义功能。
基本用法
<template>
<BaseForm
v-model="formData"
:items="formItems"
:submit-loading="loading"
submit-text="提交"
@submit="handleSubmit"
/>
</template>
<script setup>
import { BaseForm } from 'xdc-ui-lib';
const formData = reactive({
username: '',
email: '',
age: null,
gender: '',
hobbies: []
});
const formItems = [
{
name: 'username',
label: '用户名',
type: 'input',
placeholder: '请输入用户名',
required: true,
rules: [
{ required: true, message: '请输入用户名' },
{ min: 3, max: 20, message: '用户名长度为3-20个字符' }
]
},
{
name: 'email',
label: '邮箱',
type: 'input',
placeholder: '请输入邮箱',
required: true,
rules: [
{ required: true, message: '请输入邮箱' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]
},
{
name: 'age',
label: '年龄',
type: 'number',
min: 0,
max: 120
},
{
name: 'gender',
label: '性别',
type: 'radio',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' }
]
},
{
name: 'hobbies',
label: '兴趣爱好',
type: 'checkbox',
options: [
{ label: '读书', value: 'reading' },
{ label: '运动', value: 'sports' },
{ label: '音乐', value: 'music' }
]
}
];
</script>支持的表单元素类型
input: 文本输入框password: 密码输入框textarea: 多行文本框number: 数字输入框select: 下拉选择器treeSelect: 树形选择器radio: 单选框组checkbox: 复选框组checkbox-single: 单个复选框switch: 开关date: 日期选择器time: 时间选择器dateRange: 日期范围选择器slider: 滑块rate: 评分custom: 自定义组件
布局方式
<BaseForm
:items="formItems"
layout="horizontal"
:label-col="{ span: 4 }"
:wrapper-col="{ span: 20 }"
/><BaseForm :items="formItems" layout="vertical" /><BaseForm :items="formItems" layout="grid" :columns="3" />自定义插槽
<BaseForm :items="formItems">
<template #field-customField="{ item, modelValue, updateValue }">
<div class="custom-field">
<a-input
:value="modelValue"
placeholder="自定义字段"
@input="(e) => updateValue(e.target.value)"
/>
</div>
</template>
</BaseForm><BaseForm :items="formItems" :show-actions="true">
<template #actions="{ submit, reset, validateForm, formData, loading }">
<a-space>
<a-button type="primary" :loading="loading" @click="submit">确认提交</a-button>
<a-button @click="reset">重置</a-button>
<a-button type="dashed" @click="handlePreview">预览数据</a-button>
</a-space>
</template>
</BaseForm><BaseForm :items="formItems">
<!-- 只在 input 类型的表单项中可用 -->
<template #username-prefix>
<UserOutlined />
</template>
<template #username-suffix>
<InfoCircleOutlined />
</template>
<template #username-after="{ item, value }">
<small>用户名将用于登录</small>
</template>
</BaseForm><BaseForm :items="formItems">
<template #form-item-customField="{ item, modelValue, updateValue }">
<a-form-item :label="item.label">
<div class="custom-form-item">
<a-input
:value="modelValue"
placeholder="自定义表单项"
@input="(e) => updateValue(e.target.value)"
/>
<small>这是完全自定义的表单项</small>
</div>
</a-form-item>
</template>
</BaseForm><BaseForm :items="formItems">
<template #custom-items="{ formData }">
<a-form-item label="自定义表单项">
<a-input v-model:value="formData.customField" placeholder="自定义字段" />
</a-form-item>
</template>
</BaseForm>复杂表单示例
<template>
<BaseForm
ref="formRef"
v-model="formData"
:items="formItems"
:initial-values="initialValues"
:submit-loading="loading"
submit-text="创建用户"
@submit="handleSubmit"
@field-change="handleFieldChange"
>
<!-- 头像上传自定义字段 -->
<template #field-avatar="{ modelValue, updateValue }">
<div class="avatar-upload">
<a-upload
name="avatar"
list-type="picture-card"
:show-upload-list="false"
:before-upload="beforeUpload"
@change="(info) => handleAvatarChange(info, updateValue)"
>
<img v-if="modelValue" :src="modelValue" alt="avatar" />
<div v-else>
<PlusOutlined />
<div>上传头像</div>
</div>
</a-upload>
</div>
</template>
<!-- 技能标签自定义字段 -->
<template #field-skills="{ modelValue, updateValue }">
<a-select
:value="modelValue"
mode="tags"
placeholder="输入技能并按回车添加"
@change="updateValue"
/>
</template>
</BaseForm>
</template>Props
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | modelValue | 表单数据模型 | object | {} | | items | 表单项配置数组 | array | [] | | layout | 表单布局 | 'horizontal' | 'vertical' | 'grid' | 'horizontal' | | columns | 网格布局列数 | number | 2 | | labelCol | 标签列配置 | object | { span: 4 } | | wrapperCol | 控件列配置 | object | { span: 20 } | | colon | 是否显示冒号 | boolean | true | | labelAlign | 标签对齐方式 | 'left' | 'right' | 'right' | | scrollToFirstError | 是否滚动到第一个错误字段 | boolean | true | | showActions | 是否显示操作按钮 | boolean | false | | hideDefaultActions | 是否隐藏默认操作按钮 | boolean | false | | showReset | 是否显示重置按钮 | boolean | true | | submitText | 提交按钮文本 | string | '提交' | | resetText | 重置按钮文本 | string | '重置' | | submitLoading | 提交时是否显示加载状态 | boolean | false | | initialValues | 初始值 | object | {} |
Events
| 事件名 | 说明 | 回调参数 | |--------|------|----------| | update:modelValue | 模型值更新事件 | (value: object) | | submit | 提交事件 | (values: object) | | reset | 重置事件 | (values: object) | | finish | 表单提交成功事件 | (values: object) | | finish-failed | 表单提交失败事件 | (errorInfo: any) | | values-change | 表单值变化事件 | (changedValues: object, values: object) | | field-change | 字段值变化事件 | (name: string, value: any, item: object) | | field-blur | 字段失焦事件 | (name: string, value: any, item: object) | | field-search | 字段搜索事件 | (name: string, value: string, item: object) | | field-press-enter | 字段回车事件 | (name: string, value: any, item: object) |
BaseModal 模态框组件
一个增强的模态框组件,支持模态框管理和全局控制。
基本用法
<template>
<BaseModal
v-model="visible"
title="标题"
:width="600"
@ok="handleOk"
@cancel="handleCancel"
>
<p>模态框内容</p>
</BaseModal>
</template>
<script setup>
import { BaseModal } from 'xdc-ui-lib';
const visible = ref(false);
const handleOk = () => {
console.log('确认');
visible.value = false;
};
const handleCancel = () => {
console.log('取消');
visible.value = false;
};
</script>使用模态框管理
<template>
<BaseModal v-model="visible" modal-id="user-modal" title="用户信息">
<p>用户信息内容</p>
</BaseModal>
</template>
<script setup>
import { BaseModal, useModalManager } from 'xdc-ui-lib';
const { closeAllModals } = useModalManager();
const closeAll = () => {
closeAllModals();
};
</script>Props
| 参数 | 说明 | 类型 | 默认值 | |------|------|------|--------| | modelValue | 是否显示模态框 | boolean | false | | open | 是否显示模态框(与 modelValue 相同) | boolean | false | | modalId | 模态框唯一标识,用于模态框管理 | string | - |
Events
| 事件名 | 说明 | 回调参数 | |--------|------|----------| | update:modelValue | 模态框显示状态更新 | (value: boolean) | | update:open | 模态框显示状态更新 | (value: boolean) | | ok | 确认按钮点击事件 | (e: Event) | | cancel | 取消按钮点击事件 | (e: Event) | | after-close | 模态框关闭后事件 | - |
插槽
| 插槽名 | 说明 | |--------|------| | default | 模态框内容 | | title | 标题内容 | | footer | 底部内容 | | closeIcon | 关闭图标 |
模态框管理 Hook
import { useModalManager } from 'xdc-ui-lib';
const { registerModal, unregisterModal, closeAllModals } = useModalManager();方法:
registerModal(id: string, ref: ModalRef): 注册模态框unregisterModal(id: string): 注销模态框closeAllModals(): 关闭所有模态框
全局事件:
close-all-modals: 关闭所有模态框的全局事件
window.dispatchEvent(new Event('close-all-modals'));FileUpload 文件上传组件
基于 ant-design-vue 的文件上传组件,支持多选、大小限制、数量限制、删除等功能。
使用
<template>
<FileUpload
:limit="3"
:fileSizeLimit="2 * 1024 * 1024"
btnTxt="上传文件"
@select="onSelect"
@exceed="onExceed"
/>
</template>
<script setup>
import { FileUpload } from 'xdc-ui-lib';
function onSelect(files) {
console.log('已选文件:', files);
}
function onExceed(file) {
alert('文件超出大小限制: ' + file.name);
}
</script>Props
| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | accept | 接受的文件类型 | string | '' | | btnTxt | 按钮文字 | string | '上传' | | btnType | 按钮类型 | string | 'button' | | btnProps | 按钮属性 | object | {} | | limit | 最大文件数 | number | 1 | | multiple | 是否多选 | boolean | 自动由 limit 控制 | | disabled | 是否禁用 | boolean | false | | icon | 自定义图标 | 组件/函数/null | undefined | | fileSizeLimit | 单文件大小限制(字节) | number | 5242880 |
Events
| 事件名 | 说明 | 回调参数 | |--------|------|----------| | select | 文件选择后触发 | files/file | | exceed | 文件超出大小限制时 | file |
FullScreenContainer 全屏容器组件
用于页面/区域的“全屏展示”容器组件,常见于:大屏、表格/图表全屏查看、需要在不改路由的情况下临时全屏等场景。
说明:该组件为库内注册组件,可直接从
xdc-ui-lib引入使用。
基本用法
<template>
<FullScreenContainer>
<div style="height: 300px; background: #f5f5f5">内容区域</div>
</FullScreenContainer>
</template>
<script setup lang="ts">
import { FullScreenContainer } from 'xdc-ui-lib'
</script>常见用法(配合工具栏按钮)
<template>
<a-button @click="toggle">切换全屏</a-button>
<FullScreenContainer ref="fsRef">
<BaseTable :columns="columns" :data-source="dataSource" />
</FullScreenContainer>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { FullScreenContainer, BaseTable } from 'xdc-ui-lib'
const fsRef = ref<any>()
function toggle() {
// 若组件内部 expose 了方法,可在此调用(以实际实现为准)
// fsRef.value?.toggle?.()
}
</script>Props
| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| noScroll | 是否隐藏内层白色容器滚动条;false 时内层 overflow:auto,true 时内层 overflow:hidden | boolean | true |
| fill | 是否填满父容器;true 外层 width/height:100% 且内层绝对定位铺满;false 外层高度随内容(height:auto) | boolean | true |
| flex | 外层是否采用 flex(column);用于“上面标题/筛选区 + 下面表格自适应吃满剩余高度” | boolean | true |
| gutter | 外层 padding(外层与内层之间间隙) | number \| string | 16 |
| padding | 内层白色容器 padding(内容与白色容器边缘间距) | number \| string | 16 |
| background | 内层白色容器背景色 | string | '#fff' |
| maxHeight | 外层最大高度;用于“外层不滚、内层滚”的场景 | number \| string | '100vh' |
| style | 透传给内层白色容器(.fsc-content)的 style(对象或字符串) | Record<string, any> \| string | - |
| contentFill | 是否为 slot 内容自动包一层 flex 容器(flex:1; min-height:0),用于 BaseTable 等组件直接放入时可正确撑开不被压扁 | boolean | false |
Slots
| 插槽名 | 说明 | |------|------| | default | 容器内容 |
Events
当前组件未定义/抛出自定义事件。
Hooks / 工具
useModalManager 模态框管理
用于对多个 BaseModal 进行注册/注销,并支持“一键关闭全部弹窗”。
import { useModalManager } from 'xdc-ui-lib'
const { registerModal, unregisterModal, closeAllModals } = useModalManager()API:
registerModal(id: string, ref: { close?: () => void })unregisterModal(id: string)closeAllModals()
提示:
BaseModal内部会用到这个能力(如果你在业务里需要自行管理多个弹窗,也可以直接使用该 hook)。
useColumnSetting 表格列设置 Hook
用于在业务侧以 hook 方式接入列设置(显隐/排序/固定/持久化),底层复用 useColumnSettingStore 的缓存逻辑。
import { computed } from 'vue'
import { useColumnSetting, type ColumnSettingColumn } from 'xdc-ui-lib'
const baseColumns: ColumnSettingColumn[] = [
{ title: 'ID', dataIndex: 'id', key: 'id' },
{ title: '名称', dataIndex: 'name', key: 'name' },
]
const {
tableRef,
selectedColumns,
currentSize,
initColumns,
getDisplayColumnsData,
handleColumnChange,
persist,
} = useColumnSetting({
columns: () => baseColumns,
storageKey: 'user-list-columns',
disabledColumns: ['id'],
// hiddenColumns: ['action'],
// size: 'middle',
// persistOnChange: true,
})
initColumns()
const displayColumns = computed(() => {
// 仅示例:你也可以直接用 selectedColumns 过滤 checked
return getDisplayColumnsData().filter((c) => c.checked)
})核心入参(UseColumnSettingOptions):
columns:列定义(支持 ref/computed/function)storageKey:本地缓存 key(建议业务传,避免 hash 变更影响)disabledColumns?:禁止操作的列hiddenColumns?:完全隐藏且不可操作的列size?:表格密度(可选,参与缓存)persistOnChange?:列变更时是否自动写缓存(默认 true;needConfirm 场景可设 false,最后手动persist())
useFilterTypeDisplay 筛选项显示设置 Hook
用于 SearchPanel 的“筛选项显示/隐藏/排序”配置管理(存储与 ColumnSetting 类似)。
import { ref } from 'vue'
import { useFilterTypeDisplay } from 'xdc-ui-lib'
const storageKey = ref('search-panel:user-list')
const filterTypes = ref<any[]>([
{ id: 'name', label: '名称', type: 'input' },
{ id: 'status', label: '状态', type: 'select' },
])
const {
selectedItems,
init,
toggleVisibility,
onCheckAllChange,
reset,
} = useFilterTypeDisplay({
storageKey,
filterTypes,
disabledIds: ref(['name']),
})
init()国际化(i18n)
组件库内置了基础国际化能力(默认 zh-CN),并支持切换语言、以及由业务侧传入自定义语言包。
import { initI18n, setLocale, getLocale, setMessages, getMessages, zhCN, enUS } from 'xdc-ui-lib'
// 1) 在 app.use(组件库) 前/后都可以初始化(组件库 install 内部也会默认 initI18n)
initI18n({
locale: 'zh-CN',
// messages: 自定义语言包(可选)
})
// 2) 运行时切换语言
setLocale('en-US')
console.log(getLocale())
// 3) 覆盖内置语言包(可选)
setMessages({
...zhCN,
// 按 LocaleMessages 结构补齐/覆盖字段
} as any)
console.log(getMessages())可用导出:
initI18n(options?)setLocale(locale)/getLocale()setMessages(messages)/getMessages()zhCN/enUS/messagesuseI18n():组件内部/业务侧均可使用(返回t(key)等)
开发
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 构建
npm run build