列表组件,支持传入 schema 进行 CURD 相关组件(列表、新增、编辑、删除)的渲染
- antd 组件样式需要手动引入
- 相关文档可查看 docs 中的文件
import ListRender from "@hzab/list-render";
const listDM = useMemo(
() =>
new DataModel({
getListApi: "/api/v1/userinfo",
// 可用于替代 getList 的函数,处理自定义数据
getListFunc() {
return new Promise((resolve) => {
resolve({
list: [{ id: 1, menuName: "name" }],
pagination: { total: 1, current: 1 },
});
});
},
createApi: "/api/v1/userinfo",
getApi: "/api/v1/userinfo/:id",
updateApi: "/api/v1/userinfo/:id",
deleteApi: "/api/v1/userinfo/:id",
}),
[],
);
// testSchema 为 formily 生成的 schema json
<ListRender schema={testSchema} model={listDM} />;
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
className |
string |
否 |
- |
外层 div className |
idKey |
string |
否 |
id |
唯一值字段的 key |
schema |
Object |
是 |
- |
字段描述文件,包含各个字段的信息 |
model |
Object |
是 |
- |
数据模型,包含 CURD 接口信息,传入 DataModel 的实例 |
isPatchUpdate |
boolean |
否 |
false |
编辑提交接口是否使用 patch 发起请求 |
list |
Array |
|
- |
本地数据源 |
closeAutoRequest |
Boolean |
|
false |
是否关闭加载完毕后自动发起请求。true 时组件 didMount 不自动发起请求 |
hasQuery |
Boolean |
|
true |
是否包含搜索、筛选框、搜索按钮等 |
verticalHeader |
Boolean |
|
false |
搜索项和新增按钮是否处于不同的行等 |
search |
String |
|
- |
传入空字符串时,不包含搜索框;传入非空字符串时,显示搜索框,同时传入的字符串作为搜索框的占位符 |
filters |
Array |
|
[] |
字符串数组,可以包含要筛选的字段 key 值(schema 中的 name),或者字符串 '$timerange'(时间范围筛选专用) |
queryConf |
Object |
|
{} |
设置 query 参数的 key |
createText |
String/ReactNote |
|
新增 |
新增按钮文案 |
hasCreate |
Boolean |
|
true |
是否显示新增按钮 |
hasAction |
Boolean |
|
true |
是否在表格的最右增加一个“操作”列;hasAction 为 true 时,下面的 hasEdit/hasDel 才会生效 |
hasEdit |
Boolean/Function |
|
true |
是否显示编辑按钮,可传入回调控制当前行是否显示 |
hasDel |
Boolean/Function |
|
true |
是否显示删除按钮,可传入回调控制当前行是否显示 |
hasDetail |
Boolean/Function |
|
true |
是否显示详情按钮,可传入回调控制当前行是否显示 |
hasDelTips |
String/Function |
|
"确认删除该项?" |
删除按钮自定义提示,可传入回调根据当前行数据显示对应提示 |
tableConf |
Object |
|
{} |
Table 相关配置 |
tableProps |
Object |
|
{} |
直接传给 Table 的 props,相关 API 可直接参考 antd table 组件 |
fetchOnEdit |
Boolean |
|
true |
展示编辑弹框时,是否会调用一次详情接口进行回填;若为 false,则会使用表格列表接口返回的 row 数据进行回填 |
fetchById |
Boolean |
|
true |
编辑中的详情请求,是否使用 id 作为入参的 key |
dialogConf |
Object |
|
{} |
dialog 配置对象 |
dialogDetailProps |
Object |
|
{} |
dialog descriptions 配置对象 |
dialogFormProps |
Object |
|
{} |
dialog fromRender 配置对象 |
schemaScope |
Object |
|
{} |
formRender schemaScope props |
components |
Object |
|
{} |
formRender components props 自定义组件 |
detailComponents |
Object |
|
{} |
descriptions components props 自定义组件 |
hasPagination |
Boolean |
|
true |
是否显示分页 |
paginationConf |
Object |
|
{} |
可自定义 Pagination props,进行 pagination 相关设置 |
formInitialValues |
Object |
|
{} |
给新增、编辑对话框中的表单增加默认值 |
Slots |
Object |
|
{} |
组件插槽 |
getFieldListOpt |
Object |
|
{} |
getFieldList opt 参数 |
onGetListEnd |
Function |
|
- |
请求列表成功返回的回调 |
onCreateSuc |
Function |
|
- |
新增成功返回的回调 |
onEditSuc |
Function |
|
- |
编辑成功返回的回调 |
onDelSuc |
Function |
|
- |
删除成功返回的回调 |
onFormDialogClose |
Function |
|
- |
表单弹窗关闭回调 |
dialogFormMount |
Function |
|
- |
新增、编辑弹窗 Form 渲染完成回调 |
msgConf |
Object |
|
{} |
新增、编辑、删除、列表查询,详情查询的报错 msg 提示设置 |
i18n |
Object |
|
{} |
文案配置 |
queryFormInitialValues |
Object |
|
{} |
列表上方查询 Form 默认值 |
queryFormIsExtendModelQuery |
Boolean |
|
false |
列表上方查询 Form 默认值是否继承 data-model.query 置 |
- fetchOnEdit 展示编辑弹框时,是否会调用一次详情接口进行回填(某些场景下,列表接口只返回部分部分字段,只有详情接口会返回全部字段);若为 false,则会使用表格列表接口返回的 row 数据进行回填
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
colConf |
Object |
|
{} |
指定各列的配置(比如列宽),key 为字段的 name。可以指定名为 “_$actions”的字段来设置“操作”列 |
rowSelection |
Object |
|
{} |
选择功能的配置。参考 antd table rowSelection 参数 |
scroll |
Object |
|
{} |
表格是否可滚动,也可以指定滚动区域的宽、高。参考 antd table scroll 参数 |
expandable |
Object |
|
{} |
配置展开属性。参考 antd table expandable 参数 |
onRow |
Object |
|
{} |
设置行属性。参考 antd table onRow 参数 |
orderColType |
string |
|
- |
序号列数据类型:page(按当前页的序号)、all(按所有页的序号) |
orderColWidth |
string/number |
|
- |
序号列 width 的参数 |
tableEmptyValue |
string/number |
|
undefined |
table 列表空值展示数 |
isTableSortXIdex |
Boolean |
|
undefined |
table 列表列排序是否按照 x-index 排序 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
ellipsis |
boolean/Object |
|
- |
当前列是否超出隐藏,true 或 { showTitle: true } 开启超出隐藏 |
emptyValue |
string/number |
|
undefined |
table 列表单列空值展示 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
hasReset |
boolean |
|
false |
是否有重置按钮 |
isSelectSearch |
boolean |
|
true |
Select 是否支持搜索 |
isRmDefault |
boolean |
|
false |
是否去除默认值 |
isRmValidator |
boolean |
|
false |
是否去除校验 |
isChangeSubmit |
boolean |
|
true |
是否支持改变提交 |
isEnterSubmit |
boolean |
|
true |
是否支持回车提交 |
selectList |
Array
|
|
["Radio.Group", "Checkbox.Group"] |
转换为 select 的组件列表 |
inputList |
Array
|
|
["NumberPicker"] |
转换为 input 的组件列表 |
customSubmitList |
Array<{component:string,event:string}> |
|
|
自定义提交触发函数的列表 [{component: 'test', event: 'onTest'}] |
replaceComList |
Array<{name:string,"x-component":string}> |
|
|
通过 name 替换过滤项中组件 schema 对象逻辑。注意 name 必传,不传会把所有同类型 component 替换 |
queryMap |
Function |
|
- |
query 数据提交前的处理函数 |
beforeQuerySearch |
Function | Promise<boolean> |
|
- |
点击搜索按钮前触发的函数 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
query |
Object |
否 |
|
get 请求参数 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
createText |
string |
否 |
新增 |
新增按钮文案 |
tableEdit |
string |
否 |
编辑 |
表格编辑按钮文案 |
tableDel |
string |
否 |
删除 |
表格删除按钮文案 |
tableDelTip |
string |
否 |
确认删除该项? |
表格删除提示文案 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
headerActionPrefix |
Function |
否 |
|
新增按钮左侧插槽 |
headerActionSuffix |
Function |
否 |
|
新增按钮右侧插槽 |
HeaderOthersSuffix |
Function |
否 |
|
表格和搜索项之间的插槽 |
tableActionsSlot |
Function |
否 |
|
操作列插槽,会覆盖操作列 |
actionPrefixSlot |
Function |
否 |
|
操作列 编辑按钮左侧插槽 |
actionCenterSlot |
Function |
否 |
|
操作列 编辑、删除按钮中间插槽 |
actionSuffixSlot |
Function |
否 |
|
操作列 删除按钮右侧插槽 |
FormSlot |
Function |
否 |
|
新增、编辑弹窗插槽 |
dialogFooterPre |
Function |
否 |
|
新增、编辑弹窗确认及取消按钮左侧插槽 |
dialogFooterCenter |
Function |
否 |
|
新增、编辑弹窗确认及取消按钮中间插槽 |
dialogFooterSuffix |
Function |
否 |
|
新增、编辑弹窗确认及取消按钮右侧插槽 |
// Slots 按需添加
const Slots = {
headerActionPrefix() {
return (<div>headerActionPrefix</div>)
},
actionPrefixSlot(props) {
const { text, record, index, onEdit, onDel } = props;
return (<div>actionPrefixSlot</div>)
},
dialogFooterPre(props) {
const {
cancel,
onOk,
close,
form,
validate,
} = props?.options || {};
return (<div>dialogFooterPre</div>)
}
};
<ListRender schema={schema} model={listDM} Slots={Slots} />
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
width |
number/string |
否 |
|
弹窗宽度 |
okText |
string |
否 |
|
弹窗底部确定按钮文案 |
cancelText |
string |
否 |
|
弹窗底部取消按钮文案 |
footer |
Array |
否 |
|
自定义弹窗底部按钮 |
beforeSubmit |
Function |
否 |
|
提交前的回调, return false; 表示拦截,不进行请求。 |
useFormData |
boolean |
否 |
|
是否使用 form data 提交数据 |
paginationConf
- 默认参数参考 antd pagination 组件
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
pageSizeOptions |
Array |
否 |
[10, 20, 50, 100] |
可选 pageSize 数组 |
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
boxList |
Array/false |
否 |
"FormGrid", "FormGrid.GridColumn", "Card" |
配置内容需要大屏的父容器,如 "FormGrid", "FormGrid.GridColumn", "Card" |
函数名 |
参数 |
说明 |
onSearch |
query |
重置页码至 1,并刷新列表 |
getList |
query |
获取当前页列表数据 |
forceUpdate |
- |
强制重渲染列表,解决枚举数据渲染不正常的问题 |
formDialogRef |
- |
新增、编辑 弹窗 form-dialog 的 ref |
queryRef |
- |
筛选条件 query-render 的 ref |
onCreate |
- |
手动触发新增按钮相关操作 |
onEdit |
row |
手动触发编辑按钮相关操作 |
onDel |
row |
手动触发删除按钮相关操作 |
- visible: 显示(默认状态)
- hidden: 半隐藏。字段可赋值,可监听,但表单项隐藏
- none: 全隐藏。字段完全不可用。
{
"form": {
"labelCol": 6,
"wrapperCol": 12
},
"schema": {
"type": "object",
"properties": {
"test": {
"type": "string",
"title": "Input",
"x-decorator": "FormItem",
"x-component": "Input",
"x-validator": [],
"x-component-props": {},
"x-decorator-props": {},
"x-reactions": {},
"x-designable-id": "1zlm9bu3fpg",
"x-index": 0,
"name": "test",
"x-display": "none"
}
},
"x-designable-id": "ldzb3lu81dx"
}
}
- true: 在表格中展示(默认)
- false: 在表格中隐藏
{
"form": {},
"schema": {
"type": "object",
"properties": {
"test": {
"type": "string",
"title": "Input",
"x-decorator": "FormItem",
"x-component": "Input",
"x-validator": [],
"x-component-props": {},
"x-decorator-props": {},
"x-reactions": {},
"x-designable-id": "1zlm9bu3fpg",
"x-index": 0,
"name": "test",
"inTable": false
}
},
"x-designable-id": "ldzb3lu81dx"
}
}
- 通过 scenario 获取当前表单环境变量
- 属性响应中,显示/隐藏配置:scenario === 'edit'
{
"form": {},
"schema": {
"type": "object",
"properties": {
"test": {
"type": "string",
"title": "Input",
"x-decorator": "FormItem",
"x-component": "Input",
"x-validator": [],
"x-component-props": {},
"x-decorator-props": {},
"x-reactions": {
"dependencies": [
{
"property": "value",
"type": "any"
}
],
"fulfill": {
"state": {
//当涉及三层及以上的时,请使用 display,3依赖于2,2依赖于1时,编辑设置值时,3依赖于2的赋值,不会捕捉到
// 例:"display": "{{$deps.hasECert === 1 ? \"visible\" : \"hidden\"}}"
"visible": "{{scenario === 'edit'}}"
}
}
},
"x-designable-id": "1zlm9bu3fpg",
"x-index": 0,
"name": "test"
}
},
"x-designable-id": "ldzb3lu81dx"
}
}
参数名 |
说明 |
scenario |
环境参数,当前表单的环境:create、edit、query |
$self |
代表当前字段实例,可以在普通属性表达式中使用,也能在 x-reactions 中使用 |
$form |
代表当前 Form 实例,可以在普通属性表达式中使用,也能在 x-reactions 中使用 |
$deps |
只能在 x-reactions 中的表达式消费,与 x-reactions 定义的 dependencies 对应,数组顺序一致 |
$values |
代表顶层表单数据,可以在普通属性表达式中使用,也能在 x-reactions 中使用 |
$observable |
用于创建响应式对象,使用方式与 observable 一致 |
$memo |
用于创建持久引用数据,使用方式与 autorun.memo 一致 |
$effect |
用于响应 autorun 第一次执行的下一个微任务时机与响应 autorun 的 dispose,使用方式与 autorun.effect 一致 |
$props |
用于对房钱字段实例设置组件 props |
- 若存在 axios 相关配置失效的问题,请在选择一下任意一种方式解决;
- 在入口文件设置 DataModel 默认的 axios 为已配置好的 axios;
- 在入口文件对 DataModal 的 axios 进行配置;
// 设置 DataModel 默认的 axios 为已配置好的 axios;
import axios from "axios";
import { setDefaultAxios } from "@hzab/list-render";
setDefaultAxios(axios);
// 配置 DataModal 的 axios;
import axios from "axios";
import { axios as ax } from "@hzab/list-render";
setAxRequest(axios);
setAxRequest(ax);
setAxResponse(axios);
setAxResponse(ax);
// axios 守卫
export function setAxRequest(_ax) {
_ax.interceptors.request.use((config) => {
const { url = "" } = config;
if (/^\/api\/v\d+\/user\//.test(url)) {
} else if (url.startsWith("/api")) {
config.baseURL = cfg.businessApi;
}
return config;
});
}
// 请求到结果的拦截处理;
export function setAxResponse(_ax) {
_ax.interceptors.response.use(
(res) => {
// const navigateApi = useNavigate()
// const locationApi = useLocation();
if (res.data.code == 401) {
message.error(res._message || "验证信息失效,请重新登录");
// TODO: 页面跳转
return res;
}
return res;
},
(error) => {
console.error("Error axios response: ", error);
message.error(error._message || "网络异常,请稍后再试");
},
);
}
export function setAxToken(_ax, token) {
_ax.defaults.headers.Authorization = token;
}
export function setAxiosToken(token) {
setAxToken(ax, token);
setAxToken(axios, token);
}
export default axios;
import { DataModel } from "@hzab/list-render";
// 生成实例
const dataModel = new DataModel({
createApi: "api",
createMap(data) {
return data;
},
getApi: "api",
getMap(res) {
return res;
},
getListApi: "getListApi",
getListMap(item) {
return item;
},
updateApi: "updateApi",
updateMap(data) {
return data;
},
deleteApi: "deleteApi",
multipleDeleteApi: "multipleDeleteApi",
query: { pageNumber: 1, pageSize: 10 },
axiosConf: {
timeout: 10000,
},
});
// 调用方式
async function test() {
const createRes = await dataModel.create();
const getRes = await dataModel.get();
const getListRes = await dataModel.getListApi();
const updateRes = await dataModel.update();
const deleteRes = await dataModel.delete();
const multipleDeleteRes = await dataModel.multipleDelete();
}
属性名称 |
属性类型 |
必须 |
默认值 |
描述 |
createApi |
String |
|
|
post 请求的 api,dataModel. |
createMap |
Function |
|
|
post 请求提交前的处理函数 |
getApi |
String |
|
|
get 请求的 api |
getMap |
Function |
|
|
处理 get 返回结果,处理完需要把结果返回 |
getListApi |
String |
|
|
getList 获取列表的 api,返回列表数据和 pagination 数据 |
getListMap |
Function |
|
|
getList 结果 map 的回调函数,参数为结果每一项数据,处理完需要把结果返回 |
getListFunc |
Function |
|
|
可用于替代 getList 的函数,处理自定义数据,参数为 query |
updateApi |
String |
|
|
put 请求的 api |
updateMap |
Function |
|
|
put 请求提交前的处理函数 |
deleteApi |
String |
|
|
delete 请求的 api |
multipleDeleteApi |
|
|
|
批量删除请求的 api,使用的 axios({ method: 'DELETE' }) 发请求 |
query |
|
|
|
get 请求的参数 |
axiosConf |
Object |
|
|
axios 的配置项 |
- 在 config/webpack.config/webpack.config.dev.js 中按需修改 alias 配置的包名,便于本地调试
- 在 src/typings.d.ts 中按需修改 declare module 配置的包名,解决 ts 报错问题
- npm run dev
- example 本地开发测试代码
- src 组件源码
- lib 组件打包编译后的代码
- 本地运行:npm run dev
- 测试环境打包编译:npm run build-flow-dev
- 生产环境打包编译:npm run build
- 在 config/webpack.config/webpack.config.prod.js 中按需修改 entry 配置的文件名
- 编译组件:npm run build
- 命令:npm publish --access public
- 发布目录:
- 0.0.x: npm run publish-patch
- 0.x.0: npm run publish-minor
- x.0.0: npm run publish-major