oceanx-component-ui-antd
v1.0.7
Published
基于 ant-design-vue 的 Schema 驱动表格与表单组件(antd-table / antd-form)
Maintainers
Readme
oceanx-component-ui-antd
基于 Vue 3 + ant-design-vue 4 的 Schema 驱动组件库。
安装后可直接使用:
<antd-table>— CRUD 表格(搜索 / 增删改查 / 分页 / 列设置)<antd-form>— Schema 表单(分组 / 分步 / JSON 嵌套)<antd-schema-conf>— 配置页(拉取 schema + 编辑保存)
安装
npm install oceanx-component-ui-antd
# 或
pnpm add oceanx-component-ui-antd父项目只安装 Vue。ant-design-vue、@ant-design/icons-vue、dayjs 的版本由本库锁定。
npm install [email protected]快速接入
1. 全局注册(推荐)
// main.js
import { createApp } from 'vue'
import OceanxUI from 'oceanx-component-ui-antd'
import 'oceanx-component-ui-antd/style.css'
import App from './App.vue'
const app = createApp(App)
app.use(OceanxUI) // 注册 Ant Design,以及 antd-table / antd-form / antd-schema-conf
app.mount('#app')根组件建议包一层 ConfigProvider(与演示站一致):
<template>
<a-config-provider :locale="zhCN" :theme="ANTD_THEME">
<a-app>
<router-view />
</a-app>
</a-config-provider>
</template>
<script>
import { ANTD_THEME, zhCN } from 'oceanx-component-ui-antd'
export default {
setup() {
return { zhCN, ANTD_THEME }
}
}
</script>2. 按需引入
<template>
<CTable :res="tableRes" row-key-field="id" />
<CForm
v-model="formData"
:visible-fields="visibleFields"
:rules="rules"
/>
</template>
<script>
import { CTable, CForm } from 'oceanx-component-ui-antd'
import 'oceanx-component-ui-antd/style.css'
export default {
components: { CTable, CForm },
// ...
}
</script>按需引入时,组件标签为 CTable / CForm;全局注册后模板里写 antd-table / antd-form。
antd-table 表格
最小用法
<template>
<antd-table :res="tableRes" row-key-field="id" />
</template>
<script>
export default {
setup() {
const tableRes = {
code: 200,
total: 2,
data: [
{ id: 1, name: '设备A', role: 'admin' },
{ id: 2, name: '设备B', role: 'user' }
],
schema: [
{
field: 'id',
title: 'ID',
type: 'number',
hidden: ['add', 'edit']
},
{
field: 'name',
title: '名称',
type: 'text',
verify: [{ required: true, message: '名称不能为空' }]
},
{
field: 'role',
title: '角色',
type: 'select',
options: {
data: [
{ value: 'admin', name: '管理员' },
{ value: 'user', name: '用户' }
],
render: 'tag'
}
}
]
}
return { tableRes }
}
}
</script>res 也可拆开传::data + :schema + :total。
常用 Props
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
| res | Object | {} | 接口整包:{ data, schema, total } |
| data | Array | [] | 行数据(无 res 时) |
| schema | Array | [] | 字段 Schema |
| total | Number | 0 | 总数 |
| row-key-field | String | 'id' | 行主键 |
| search-fields | Object/Array | {} | 搜索字段,推荐对象:{ name: true, role: { multiple: true, default: ['admin'] } } |
| search-cols | Number | 3 | 搜索区列数 |
| api | Object/false | false | 远程 CRUD,见下方 |
| params | Object | {} | 列表固定查询参数 |
| options | Object | — | actionButtons / toolbarButtons / showSelection 等 |
| file-props | Object | {} | 上传配置 |
| form-layout | Object | { cols: 2, labelPlacement: 'top' } | 弹窗表单布局 |
| cols | Number | 0 | 表单列数(优先于 formLayout.cols) |
| sorts / filters | Object | {} | 列排序 / 筛选配置 |
| is-card-list | Boolean | false | 卡片列表模式 |
| show-selection | Boolean | true | 多选列(仅此开关控制,与 batch-delete 解耦) |
远程 API
const api = {
get: (query) => axios.get('/api/list', { params: query }),
add: (row) => axios.post('/api/add', row),
edit: (row) => axios.put('/api/edit', row),
del: (row) => axios.delete(`/api/del/${row.id}`),
// 可选
export: (query) => axios.get('/api/export', { params: query, responseType: 'blob' })
}<antd-table
:api="api"
row-key-field="id"
:search-fields="{
name: true,
role: { multiple: true, default: ['admin'] }
}"
/>列表请求默认会带:
{
schema: true,
pageable: {
current_page: 1,
page_size: 10
}
// ...搜索条件、排序等
}接口约定:列表返回 { code, data: [], schema: [], total };code === 200 视为成功。
常用事件
| 事件 | 说明 |
|---|---|
| search | 点击搜索 |
| create / update / delete / clone | 单行变更 |
| batch-delete | 批量删除 |
| sort / filter / table-change | 表头排序筛选 |
| update:page / update:page-size | 分页 |
常用插槽
<antd-table :res="tableRes" row-key-field="id">
<!-- 自定义列 -->
<template #column-amount="{ text }">
¥ {{ text }}
</template>
<!-- 自定义表单字段 -->
<template #form-amount="{ field, modelValue, form, disabled }">
<a-input-number
:value="modelValue"
:disabled="disabled"
@update:value="(v) => (form[field.field] = v)"
/>
</template>
<!-- 工具栏扩展 -->
<template #toolbar-buttons>
<a-button>自定义</a-button>
</template>
<!-- 行操作扩展 -->
<template #action-cell="{ row }">
<a-button type="link" @click="onDetail(row)">详情</a-button>
</template>
</antd-table>antd-form 表单
适合弹窗内或独立配置页。需自行传入 v-model、可见字段与校验规则。
<template>
<antd-form
ref="formRef"
v-model="formData"
:visible-fields="visibleFields"
:json-fields="jsonFields"
:rules="rules"
:cols="2"
dialog-type="edit"
:file-props="fileProps"
:submit-handler="handleSubmit"
/>
<a-button type="primary" @click="onSave">保存</a-button>
</template>
<script>
import { ref, computed } from 'vue'
import { _collectFormRules } from 'oceanx-component-ui-antd'
export default {
setup() {
const formRef = ref(null)
const formData = ref({ name: '', config: {} })
const schema = [
{ field: 'name', title: '名称', type: 'text' },
{
field: 'config',
title: '配置',
type: 'json',
json: [
{ field: 'host', title: '地址', type: 'text' }
]
}
]
const visibleFields = computed(() =>
schema.filter((f) => f.type !== 'json')
)
const jsonFields = computed(() =>
schema.filter((f) => f.type === 'json')
)
const rules = _collectFormRules(schema)
async function handleSubmit(payload) {
await api.save(payload)
return { code: 200 }
}
async function onSave() {
await formRef.value?.submit()
}
return {
formRef,
formData,
visibleFields,
jsonFields,
rules,
handleSubmit,
onSave
}
}
}
</script>常用 Props
| Prop | 类型 | 说明 |
|---|---|---|
| modelValue / v-model | Object | 表单数据 |
| visible-fields | Array | 普通字段 schema(必填) |
| json-fields | Array | type: 'json' 字段 |
| rules | Object | ant-design-vue Form rules |
| cols / form-layout | Number / Object | 列布局 |
| dialog-type | String | add / edit / view 等,影响 hidden/disable |
| api | Object | { add, edit } |
| submit-handler | Function | 自定义提交 |
| file-props | Object | 上传 |
| disabled | Boolean | 整表禁用 |
暴露方法
通过 ref 调用:submit()、validate()、resetFields() 等(以组件 expose 为准)。
配置页场景更推荐直接用 <antd-schema-conf>,内部已包好 antd-form + 编辑/保存。
antd-schema-conf 配置页
<template>
<antd-schema-conf
:res="confRes"
:api="confApi"
:cols="2"
:file-props="fileProps"
@submit="onSubmit"
/>
</template>
<script>
export default {
setup() {
const confRes = {
data: { title: '系统配置', retry: 3 },
schema: [
{ field: 'title', title: '标题', type: 'text' },
{ field: 'retry', title: '重试次数', type: 'number' }
]
}
const confApi = {
get: () => axios.get('/api/conf'),
edit: (data) => axios.put('/api/conf', data)
}
function onSubmit(payload) {
console.log('已保存', payload)
}
return { confRes, confApi, onSubmit }
}
}
</script>有 res.data 时优先用本地数据;否则走 api.get。保存走 api.edit,无 api 时抛出 submit 事件。
Schema 字段约定
{
field: 'name', // 字段名
title: '名称', // 标题
type: 'text', // 类型,见下表
default: null, // 默认值
order: 0, // 排序
width: 160, // 列宽
verify: [], // 校验规则
options: { // 选项类字段
data: [{ value, name, color }],
render: 'tag' // 列表渲染:tag / switch 等
},
hidden: ['add', 'edit'], // 场景隐藏
disable: ['edit'], // 场景禁用
bind: [], // 联动
json: [], // type=json 时子字段
jsonOptions: {} // 动态 json schema
}支持的 type
| type | 说明 |
|---|---|
| text / str / textarea / password | 文本 |
| number / int / float | 数字 |
| select / checkbox / radio | 选择 |
| treeselect / cascader | 树 / 级联 |
| switch / bool | 开关 |
| date / datetime / time | 日期时间 |
| file / file-multiple | 文件 |
| base64 / image | Base64 / 图片 |
| tags / slider / progress | 标签 / 滑块 / 进度 |
| list[int] / list[float] / list[str] | 列表 |
| splice | 拼接 |
| json | 嵌套对象 / 数组表 |
| slot | 外部插槽自定义 |
| group | 分组标题 |
文件上传 file-props
const fileProps = {
fileUrl: '/api/file/upload',
headers: { Authorization: 'Bearer xxx' },
name: 'file',
data: { scene: 'crud' },
beforeUpload: (file) => true,
onSuccess: (res, file) => {},
onError: (err, file) => {},
onRemove: (file) => true
}主题
import { ANTD_THEME, CSS_VARS, _applyCssVars } from 'oceanx-component-ui-antd'
// 传给 a-config-provider :theme="ANTD_THEME"
// 或自定义 CSS 变量后再写入
_applyCssVars({
...CSS_VARS,
'--var-primary-color': '#0958D9'
})安装插件时默认会执行 _applyCssVars()。若业务自行管理变量:
app.use(OceanxUI, { applyCssVars: false })自定义组件前缀:
app.use(OceanxUI, { prefix: 'ox' })
// 则使用 <ox-table> <ox-form>本地开发 / 发布
# 演示站
npm run dev
# 打演示站产物 → demo-dist/
npm run build
# 打 npm 包产物 → dist/
npm run build:lib
# 发布(需已登录 npm / 私有源)
npm publish
# 或私有源:
# npm publish --registry=https://your-registry/prepublishOnly 会在 publish 前自动执行 build:lib。
导出一览
| 导出 | 说明 |
|---|---|
| default / install | Vue 插件 |
| CTable / CRUDTable | 表格 |
| CForm / CRUDForm | 表单 |
| CSchemaConf / SchemaConf | 配置页 |
| fieldComponents | 字段组件映射 |
| _collectFormRules | 从 schema 生成校验规则 |
| ANTD_THEME / CSS_VARS / _applyCssVars | 主题 |
| zhCN | 中文语言包 |
注意事项
- 父项目执行
app.use(OceanxUI)即可,其中会注册 Ant Design。 - 建议外层使用
<a-app>,以便 Message / Modal 等上下文正常。 - 样式引入
oceanx-component-ui-antd/style.css。Ant Design 的 reset 已打进该文件。 - 父项目安装
[email protected]。[email protected]、@ant-design/[email protected]、[email protected]随本库安装。
