Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@hzab/list-render
Advanced tools
列表组件,支持传入 schema 进行 CURD 相关组件(列表、新增、编辑、删除)的渲染
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 的实例 |
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 | 是否显示删除按钮,可传入回调控制当前行是否显示 | |
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 配置对象 | |
schemaScope | Object | {} | formRender schemaScope props | |
components | Object | {} | formRender 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置 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
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 列表空值展示数 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
ellipsis | boolean/Object | - | 当前列是否超出隐藏,true 或 { showTitle: true } 开启超出隐藏 | |
emptyValue | string/number | undefined | table 列表单列空值展示 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
hasReset | boolean | false | 是否有重置按钮 | |
queryMap | Function | - | query 数据提交前的处理函数 | |
beforeQuerySearch | Function | Promise<boolean> | - | 点击搜索按钮前触发的函数 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
query | Object | 否 | get 请求参数 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
createText | string | 否 | 新增 | 新增按钮文案 |
tableEdit | string | 否 | 编辑 | 表格编辑按钮文案 |
tableDel | string | 否 | 删除 | 表格删除按钮文案 |
tableDelTip | string | 否 | 确认删除该项? | 表格删除提示文案 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
headerActionPrefix | Function | 否 | 新增按钮左侧插槽 | |
headerActionSuffix | 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 提交数据 |
属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
---|---|---|---|---|
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 | 手动触发删除按钮相关操作 |
{
"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"
}
}
{
"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"
}
}
{
"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 |
// 设置 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 的配置项 |
FAQs
列表组件,支持传入 schema 进行 CURD 相关组件(列表、新增、编辑、删除)的渲染
The npm package @hzab/list-render receives a total of 5 weekly downloads. As such, @hzab/list-render popularity was classified as not popular.
We found that @hzab/list-render demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.