# oceanx-component-ui-antd

> 基于 ant-design-vue 的 Schema 驱动表格与表单组件（antd-table / antd-form）

Latest version **1.0.4** (published 2026-09-24) · UNLICENSED license · 0 weekly downloads

## Install

```sh
npm install oceanx-component-ui-antd
pnpm add oceanx-component-ui-antd
yarn add oceanx-component-ui-antd
bun add oceanx-component-ui-antd
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 1.0.4 |
| Published | 2026-09-24 |
| First published | 2026-09-24 |
| Weekly downloads | 0 |
| License | UNLICENSED |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 2 |
| Unpacked size | 362.2 KB |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| Maintainers | sjw_zkqh_1 |
| Keywords | vue, vue3, ant-design-vue, schema, crud, table, form, antd-table, antd-form |

## Links

- npm: https://www.npmjs.com/package/oceanx-component-ui-antd
- npm.io page: https://npm.io/package/oceanx-component-ui-antd

## Dependencies (2)

- [core-js](https://npm.io/package/core-js.md) 3.50.0
- [esbuild](https://npm.io/package/esbuild.md) 0.21.5

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.0.4 (latest) — 2026-09-24
- 1.0.3 — 2026-09-24
- 1.0.2 — 2026-09-24
- 1.0.1 — 2026-09-24
- 1.0.0 — 2026-09-24

## README

# oceanx-component-ui-antd

基于 **Vue 3 + ant-design-vue 4** 的 Schema 驱动组件库。

安装后可直接使用：

- `<antd-table>` — CRUD 表格（搜索 / 增删改查 / 分页 / 列设置）
- `<antd-form>` — Schema 表单（分组 / 分步 / JSON 嵌套）
- `<antd-schema-conf>` — 配置页（拉取 schema + 编辑保存）

---

## 安装

```bash
npm install oceanx-component-ui-antd
# 或
pnpm add oceanx-component-ui-antd
```

**Peer 依赖**（业务项目需自行安装）：

```bash
npm install vue ant-design-vue @ant-design/icons-vue dayjs
```

---

## 快速接入

### 1. 全局注册（推荐）

```js
// main.js
import { createApp } from 'vue'
import Antd from 'ant-design-vue'
import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
import 'ant-design-vue/dist/reset.css'

import OceanxUI, { ANTD_THEME } from 'oceanx-component-ui-antd'
import 'oceanx-component-ui-antd/style.css'

import App from './App.vue'
import zhCN from 'ant-design-vue/es/locale/zh_CN'

dayjs.locale('zh-cn')

const app = createApp(App)
app.use(Antd)
app.use(OceanxUI) // 注册 antd-table / antd-form / antd-schema-conf
app.mount('#app')
```

根组件建议包一层 ConfigProvider（与演示站一致）：

```vue
<template>
  <a-config-provider :locale="zhCN" :theme="ANTD_THEME">
    <a-app>
      <router-view />
    </a-app>
  </a-config-provider>
</template>

<script>
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import { ANTD_THEME } from 'oceanx-component-ui-antd'

export default {
  setup() {
    return { zhCN, ANTD_THEME }
  }
}
</script>
```

### 2. 按需引入

```vue
<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 表格

### 最小用法

```vue
<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` 为布尔值时覆盖下方同名 prop |
| `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` | 多选列，与批量删除按钮无关 |

### 远程 API

```js
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' })
}
```

```vue
<antd-table
  :api="api"
  row-key-field="id"
  :search-fields="{
    name: true,
    role: { multiple: true, default: ['admin'] }
  }"
/>
```

未搜索、未点表头排序时，`api.get` 收到的参数是：

```js
{
  schema: true,
  desc: ['id'],
  pageable: {
    current_page: 1,
    page_size: 10
  }
}
```

搜索、排序、筛选会叠到同一对象上：

- 文本类搜索字段写成模糊条件，例如搜名称「设备」→ `name: { like: '设备' }`
- 日期范围收成 `time_query: { name, start_time, end_time }`，原字段不再平铺
- 表头降序 → `desc: ['字段名']`；升序 → `asc: ['字段名']`，此时不再带默认 `desc: ['id']`
- 有列筛选时带 `filters`
- `params` 里的固定条件会合并进来；其中的 `schema`、`pageable` 会覆盖默认值，缺了仍会补回 `schema: true` 和完整 `pageable`

接口约定：列表返回 `{ code, data: [], schema: [], total }`；`code === 200` 视为成功。

### 常用事件

| 事件 | 说明 |
|---|---|
| `search` | 点击搜索 |
| `create` / `update` / `delete` / `clone` | 单行变更 |
| `batch-delete` | 批量删除 |
| `sort` / `filter` / `table-change` | 表头排序筛选 |
| `update:page` / `update:page-size` | 分页 |

### 常用插槽

```vue
<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`、可见字段与校验规则。

```vue
<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()`。分步表单还可读 `isStepsMode`、`currentStep`，并调用 `nextStep()`、`prevStep()`。

配置页场景更推荐直接用 **`<antd-schema-conf>`**，内部已包好 `antd-form` + 编辑/保存。

---

## antd-schema-conf 配置页

```vue
<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 字段约定

```js
{
  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

```js
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
}
```

---

## 主题

```js
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()`。若业务自行管理变量：

```js
app.use(OceanxUI, { applyCssVars: false })
```

自定义组件前缀：

```js
app.use(OceanxUI, { prefix: 'ox' })
// 则使用 <ox-table> <ox-form>
```

---

## 本地开发 / 发布

```bash
# 演示站
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` | 主题 |

---

## 注意事项

1. 必须先 `app.use(Antd)`，组件依赖 ant-design-vue。
2. 建议外层使用 `<a-app>`，以便 Message / Modal 等上下文正常。
3. 样式需引入：`oceanx-component-ui-antd/style.css` 与 `ant-design-vue/dist/reset.css`。
4. Vue 版本建议 `^3.4`，ant-design-vue 建议 `^4`。

---
_Source: https://npm.io/package/oceanx-component-ui-antd · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
