UNPKG

@qin-ui/antd-vue-pro

Version:
165 lines (115 loc) 14.5 kB
# @qin-ui/antd-vue-pro 基于 ant-design-vue v4`a-` 前缀)封装的 Schema 驱动组件库。 用 JS 配置对象描述 UI,不写 `<a-*>` 模板堆叠。ProForm/ProTable 是渲染引擎,所有真实 UI 来自 ant-design-vue。 ## 安装与使用 ```bash pnpm add @qin-ui/antd-vue-pro # peerDeps: ant-design-vue ^4, vue ^3.5 ``` ```ts // 按需引入(推荐) import { ProForm, ProTable, useForm, useTable } from '@qin-ui/antd-vue-pro'; ``` ## 核心心智模型 **1. 配置驱动**:`useForm(数据, Field[])` / `useTable({ columns, searchFields })` 生成实例,组件接收实例。 **2. 属性分层透传**(最关键):Field 上的属性被"剥离到不同 DOM 层",不是全塞给输入控件。写错层就失效: | 属性 | 落到哪一层 | 说明 | | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------- | :------------- | | `span`/`offset`/`push`/`pull`/`flex`/`xs..xxl` | `<a-col>` Grid 层 | 仅 grid 开启时 | | `label`/`rules`/`tooltip`/`colon`/`labelAlign`/`labelCol`/`wrapperCol`/`extra`/`help`/`validateFirst`/`validateTrigger`/`valuePropName`/`normalize`/`required`/`formItemClass`/`formItemStyle`/`formItemDataAttrs` | `<a-form-item>` 层 | 表单项 | | `disabled`/`placeholder`/`allowClear`/`options`/`mode`/`maxlength`/`componentClass`/`componentStyle`/`componentDataAttrs` + 该控件其余 ant 原生属性 | 输入控件本身(a-input 等) | 其余全部 | | `component`/`hidden`/`modelProp`/`valueFormatter`/`fields`/`slots`/`formItemContainer`/`componentContainer`/`extraProps` | ProForm 逻辑消费,**不绑到 DOM** | 框架级 | > 规则:`span` 给 Grid,`label`/`rules` 给 FormItem,其余给输入控件。 ## 速查 ### component 映射(Field.component 字符串 -> ant-design-vue 组件) `input`->Input · `textarea`->TextArea · `input-password`->InputPassword · `input-search`->InputSearch · `input-number`->InputNumber · `select`->Select · `cascader`->Cascader · `date-picker`->DatePicker · `range-picker`->RangePicker · `time-picker`->TimePicker · `checkbox-group`->CheckboxGroup · `radio-group`->RadioGroup · `switch`->Switch · `slider`->Slider · `tree-select`->TreeSelect · `transfer`->Transfer · `custom`->用户自定义组件 > 写 Field 中输入控件的具体属性前,**属性名/类型以 https://antdv.com 官方文档为准**。 ### 隐式默认行为(INJECT_CONFIG,易踩坑)`ProComponentProvider` 注入,优先级低于 Field 配置。**不写也有这些默认值,需知晓以免行为与预期不符:** | component | 默认预设 | | :--------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `switch` | `{ modelProp: 'checked' }` -> v-model 绑 `checked` 而非 `value` | | `input` / `input-password` | `{ maxlength: 100, allowClear: true, placeholder: '请输入' }` | | `textarea` | `{ maxlength: 200, autoSize: {minRows:3,maxRows:6}, showCount: true, allowClear: true, placeholder: '请输入' }` | | `input-number` | `{ max: 1e15-1, min: -(1e15+1), controls: false, placeholder: '请输入', style:{width:'100%'} }` | | `select` / `cascader` | `{ allowClear: true, placeholder: '请选择', getPopupContainer }` | | `date-picker` / `range-picker` / `time-picker` | `{ allowClear: true, getPopupContainer, style:{width:'100%'} }` | | `pro-form` | `{ grid: { gutter: {xs:8, sm:16, md:16, lg:24} } }` | | `pro-form-item` | `{ validateFirst: true, span: 8 }` | | `pro-table` | `{ pagination:{showTotal, showSizeChanger, pageSizeOptions:['10','20','30','40','50','100'], showQuickJumper:true}, searchFormConfig:{layout:'grid', expand:{minExpandRows:2, expandStatus:false}}, control:true, addIndexColumn:true }` | > `modelProp` 控制 v-model 绑定名,默认 `'value'`->`v-model:value`。 > `date-picker` 支持按 picker 子类型分别预设:`date-picker.date` / `.week` / `.month` / `.year` / `.quarter`,默认值同上。 > `input-search` / `checkbox-group` / `radio-group` / `slider` / `tree-select` / `transfer` 无预设(`{}`)。 ### 不支持响应式的属性(不能包 ref/computed) `component` / `formItemContainer` / `componentContainer` / `valueFormatter` / `fields` / `slots` / `modelProp`## 实例成员速查 ### useForm -- 表单实例 ```ts useForm(initFormData, Field[], root = true) // 重载一(常用):初始数据 + 字段配置 useForm(true | false) // 重载二:仅拿实例(root) ``` 返回 `Form` 实例(**`formData` 是 reactive 对象,不用 `.value`**): | 成员 | 说明 | | :------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------- | | `form.formData` | 响应式数据,可直接读写,支持深层路径 `formData.address.city` | | `form.getFormData(path)` | 路径读取;无参返回 `undefined` | | `form.setFormData(path, value)` / `setFormData(path, prev=>new)` | 路径写入,支持函数式 | | `form.setFormData({...})` / `setFormData(prev => ({...prev, name:'新'}))` | 批量覆盖整个表单,支持函数式(先清空再写入) | | `form.fields` | 字段配置数组(Ref) | | `form.getField(path)` / `getField(fn)` | 字段查找,支持路径或查找函数;`{all:true}` 返回所有匹配数组 | | `form.setField(path, patch)` / `setField(path, prev=>({...}))` | 字段增改查;默认合并,`{updateType:'rewrite'}` 覆盖;支持函数式更新;`{all:true}` 批量更新所有匹配 | | `form.deleteField` / `form.appendField` / `form.prependField` / `form.getParentField` | 字段增删查;均支持 `{all:true}``appendField(undefined, f)` 末尾追加、`prependField(undefined, f)` 开头插入,入参可为数组 | | `form.formRef` | 底层 ant Form 实例引用(Ref),`formRef.value?.validate()` / `.resetFields()` | ### useTable -- 表格实例 ```ts useTable({ columns, dataSource, pageParam, searchParam, searchFields }); ``` 返回 `Table` 实例: | 成员 | 说明 | | :-------------------------------------------------------------------- | :----------------------------------------------------- | | `table.columns` / `table.dataSource` | 列配置 / 数据源(Ref) | | `table.pageParam` | 分页参数(reactive):`current` / `pageSize` / `total` | | `table.searchForm` | 搜索表单实例(Form 类型,所有 useForm 方法可用) | | `table.setColumn` / `deleteColumn` / `appendColumn` / `prependColumn` | 列增删改查(用法同 setField,支持 `{all:true}`) | | `table.setPageParam(patch)` | 设置分页参数 | | `table.resetQueryParams()` | 重置分页到第一页 + 恢复搜索条件到初始值 | ## 关键约定 ### 自定义组件 `Field.component` 解析优先级(高 -> 低):`teleport 插槽注入` > `ProComponentProvider.componentMap` > `内置 componentMap` > `原始 component 值`。 四种接入方式(完整代码见 skills): - **方式 1** `markRaw(SFC)`:单字段复用 SFC(**必须 markRaw**,否则被 Vue 深度代理触发性能警告) - **方式 2** render 函数 `(props, ctx) => VNode`:需动态拼装 props - **方式 3** `ProComponentProvider` 注入 `componentMap`:全局复用 / 覆盖内置组件,可追加 `declare module` 声明获强类型 - **方式 4** 模板 scoped slot:插槽名 = 字段 `path``v-bind="scoped"` 转发(teleport 机制,优先级最高) 约定:默认 v-model 绑 `value`,他 prop 用 `modelProp` 指定;组件会收到 `path` prop;除框架级属性外其余作 attrs 透传。 ### valueFormatter -- 字段值转换 控制表单值与组件值之间的转换。**在表单数据写入前(computed setter 中)执行**,支持两种形态: ```ts // 函数形态:(新值, 旧值) => 转换后的值,写回 formData。仅 set(写入)方向生效,读取时不转换 { path: 'name', valueFormatter: (val, oldVal) => val?.trim() } // 对象形态:get 读出时转换,set 写入时转换(双向) { path: 'birthday', component: 'date-picker', valueFormatter: { get: v => v ? dayjs(v) : null, set: v => v ? dayjs(v).format('YYYY-MM-DD') : null } } ``` ### ProTable -- 配置驱动表格 透传所有 ant-design-vue `TableProps``& TableProps`),可直接写 `row-key` / `bordered` / `scroll` / `row-selection` 等原生属性;`size``loading` 是 v-model。 关键 prop:`table`(useTable 实例)、`search`(数据查询方法 `() => Promise`,ProTable 内部调用,非自动触发)、`addIndexColumn``immediateSearch``control``searchFormConfig`(含 `hidden`/`container`/`layout`/`expand`)、`tableContainer`。 **数据流**:搜索->重置分页到第 1 页->调 `search()`;分页/排序变化->更新 `pageParam`->调 `search()`;重置->`resetQueryParams()`->调 `search()`### Column -- 列配置 继承 ant-design-vue `ColumnType`,所有原生列属性可用。新增:`dataIndex`(列数据路径,主用,支持 `'name'` / `'address.city'` / `['address','city']`)、`key`(辅助标识,优先级更低)、`hidden`(隐藏该列,配合列控制)。 ## 反模式 - ❌ 在 `<ProForm>` 内手写 `<a-form-item>` -- ProForm 从 Field 配置自动渲染。 - ❌ 猜透传属性名 -- 先查 antdv.com。 - ❌ 把 `span` 当输入控件属性。 - ❌ 传 SFC 给 `component` 不用 `markRaw`。 - ❌ 在 ProTable 上忘了传 `:search`,或期望它自动请求 -- 查询由你提供并驱动。 ## 按需深查 完整 API(详细签名、参数表、完整示例、ProTable Slots、ProComponentProvider 用法): - `.agents/skills/antd-vue-pro/SKILL.md` — skills 入口(速查 + 参考导航) - `.agents/skills/antd-vue-pro/references/README.md` — 完整使用文档与进阶示例 - `.agents/skills/antd-vue-pro/references/api.md` — 结构化 API 元数据 - `node_modules/@qin-ui/antd-vue-pro/README.md` — 完整用法与进阶示例 - ant-design-vue 组件属性查阅官方文档:https://antdv.com