data-list-manager
一、场景和形态
对UI、交互、数据进行高级封装的组件,提供完整的数据列表生命周期管理。数据组件边界颇多,要特别注意数据类型转换问题,目前建议统一使用字符串维护组件数据。
现场演示
下面这个界面,是由axue-data-list-manager
组件渲染
演示代码如下:
html
<!--在vitepress中的.md文件中直接引入下面的代码-->
<div id="container"></div>
<script setup>
import('axue').then(({showTip}) => {
const componentName ='axue-data-list-manager'
const el = document.createElement(componentName);
let data =[{
prdId:1,
title:"傲雪项目",
corp:"傲雪公司",
owner:"傲雪",
tel:"17788889999",
createTime:"1700364852738",
},{
prdId:2,
title:"青松项目",
corp:"青松公司",
owner:"青松",
tel:"14455556666",
createTime:"1700364852738",
axueMarking:{ //组件支持的特殊条级标记
notDelete:true, //表示该行不能删除
status:"正常", //状态名
statusType:"nomal" //正常
}
}]
let args={
caption:"我的项目",
addText:"添加项目",
dataType:{ //定义特殊的字段类型,对应有处理机制
"prdId":"number",
"tel":"telephone",
},
idField:"prdId", //指明索引字段,必须有
showFieldInList:["title","corp"], //列表中要显示的字段范围
showFieldInAdd:["corp","owner","tel"], //新增页要显示的可输入字段范围,如果包含索引字段,则表示允许用户填
showFieldInUpdate:["corp","owner","tel"], //编辑页要显示的可修改字段范围,如果包含索引字段,则表示用户可修改
showFieldInDetail:["corp","owner","tel"], //详情页要显示的字段范围,默认全部。
dataMarking:{ //定义特殊的字段,使用标识进行业务分类
classifyField:"xx",
icon:"XXurl"
},
onAddRow(dataListManager,rowdata){
console.log("onAddRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onUpdateRow(dataListManager,rowdata){
console.log("onUpdateRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onDeleteRow(dataListManager,rowdata){
console.log("onDeleteRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onClickRow(dataListManager,rowdata){
console.log("onClickRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onPulldown(dataListManager){
console.log("onPulldown回调:",dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
}
//对于行级操作,如果内置的删除、编辑功能不够,可以通过extendFunc参数进行功能扩展
let extendFunc=[
{
label:"访问文件夹",
onClick:function (){}
}
]
el.args = args
el.data=data
el.extendFunc=extendFunc
document.getElementById('container')?.appendChild(el);
});
</script>
二、使用方式
使用组件
HTML
<axue-data-list-manager
.args=${args}
.data=${data}
.extendFunc=${extendFunc}
></axue-data-list-manager>
需要定义并传入三类参数:属性、数据、菜单扩展,其中extendFunc可以不传,则默认对每一行内置提供了编辑和删除两个功能,下面依次说明。
定义属性
需要遵循数据定义规范
JavaScript
//分别定义数据实例和数据结构
let data =[{
prdId:1,
title:"傲雪项目",
corp:"傲雪公司",
owner:"傲雪",
tel:"17788889999",
createTime:"1700364852738",
},{
prdId:2,
title:"青松项目",
corp:"青松公司",
owner:"青松",
tel:"14455556666",
createTime:"1700364852738",
axueMarking:{ //组件支持的特殊条级标记
notDelete:true, //表示该行不能删除
status:"正常", //状态名
statusType:"nomal" //正常
}
}
]
let args={
caption:"我的项目",
addText:"添加项目",
dataType:{ //定义特殊的字段类型,对应有处理机制
"prdId":"number",
"tel":"telephone",
}
idField:"prdId", //指明索引字段,必须有
showFieldInList:["title","corp"], //列表中要显示的字段范围
showFieldInAdd:["corp","owner","tel"], //新增页要显示的可输入字段范围,如果包含索引字段,则表示允许用户填
showFieldInUpdate:["corp","owner","tel"], //编辑页要显示的可修改字段范围,如果包含索引字段,则表示用户可修改
showFieldInDetail:["corp","owner","tel"], //详情页要显示的字段范围,默认全部。
dataMarking:{ //定义特殊的字段,使用标识进行业务分类
classifyField:"xx",
icon:"XXurl"
}
onAddRow(dataListManager,rowdata){
console.log("onAddRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onUpdateRow(dataListManager,rowdata){
console.log("onUpdateRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onDeleteRow(dataListManager,rowdata){
console.log("onDeleteRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onClickRow(dataListManager,rowdata){
console.log("onClickRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
onPulldown(dataListManager){
console.log("onPulldown回调:",dataListManager)
//接下来处理数据同步和修正的正异常逻辑
},
}
//对于行级操作,如果内置的删除、编辑功能不够,可以通过extendFunc参数进行功能扩展
let extendFunc=[
{
label:"访问文件夹",
onClick:function (){}
}
]
注入事件回调
下拉回调
JavaScript
/**
如果数据是分批提供的,需要处理增量逻辑
*/
function onPulldown(dataListManager ){ //传入当前组件对象,用于刷新数据
//接下来处理业务
//获取当前组件数据的尺寸
const lenght = dataListManager.data.lenght
const pageSize = 10
const page=lenght/10
//模拟异步请求,实际应用中应该调用后端接口
const response = await fetch(`https://api.example.com/data?page=${page}&pageSize=${pageSize}`);
const newData = await response.json();
// 将获取到的新数据添加到组件的数据中
dataListManager.data = [...dataListManager.data, ...newData];
}
新增回调
JavaScript
/**
前端--服务端的数据同步链路过程,组件不关心
回调前,内存数据已经提前做了新增
如果同步错误,需要开发者在回调中特别处理数据数据
特别注意:
为了精准渲染性能,新增时,即便不指定可编辑id,组件也会生成一个唯一的临时id
如果数据的实际id是由后端生成的,或者前端其他规则生成的,也需要在回调中特别处理
*/
function onAddRow(dataListManager,rowdata){
console.log("onAddRow回调:",rowdata, dataListManager)
//接下来处理数据同步和修正的正异常逻辑
}
更新回调
JavaScript
/**
更新增一样,但只需要特别处理数据同步的正异常逻辑
*/
function onUpdateRow(dataListManager,rowdata){ //传入用户新增的一条数据
//接下来处理数据同步的逻辑
}
删除回调
JavaScript
/**
更新增一样,但只需要特别处理数据同步的正异常逻辑
*/
function onDeleteRow(dataListManager,rowdata){ //传入用户新增的一条数据
//接下来处理数据同步的逻辑
}
点击数据条的回调
JavaScript
/**
如果不定义点击回调,则默认会打开组件的详情查看页
注意,如果定义了回调,则不再打开详情页,这是二选一的设计
*/
function onClickRow(dataListManager,rowdata){ //传入用户点击的那一条数据
//接下来处理跳转逻辑
}
属性项
内联属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
caption | 列表标题,显示在列表左上方 | string | "我的列表" |
addText | 新增组件的文本 | string | "添加" |
isBorderDivide | 数据表格和标题之间是否显示线条间隔,一般在不显示数据表格边框时使用 | bool | false |
isShowTableBorder | 数据表格是否显示边框 | bool | false |
isClickRowShowDetail | 是否点击一条数据时,进入详情页。该配置如果存在与否,不影响@clickRow事件回调 | bool | true |
idField | 一条数据的唯一索引字段,增删交互必备 | string | null |
showFieldInList | 列表中要显示的字段范围。 注意,列表宽度限制,一般不超过4个 | array | [] |
showFieldInAdd | 新增页要显示的可输入字段范围。注意,如果不包含索引字段,则表示索引允许用户填,会自动生成一个uuid占位 | array | [] |
showFieldInUpdate | 编辑页要显示的可修改字段范围。 注意,如果不允许用户修改索引,则不要包含索引字段 | array | [] |
showFieldInDetail | 详情页要显示的字段范围,默认全部 | bool | true,默认自动生成uuid。 但对于数字类型的id,会被忽略 |
dataType | 数据处理类型定义集:默认所有涉及字段都采用文本处理方式,如果不是,则应以字段名:处理类型进行申明 | ||
number | 数字 | function | 会自动转为字符串显示,更新时回传数字 |
image | 图片 | function | 会将值视为src |
telephone | 电话 | function | 新增编辑都需要走认证流程交互 |
file | 文件 | function | 支持上传修改交互 |
事件回调注册,回调入参详见范例,正常是第一个参数是组件本身,row级方法第二个参数会传入行数据 | |||
onAddRow | 新增页面回调,返回用户新建的一条数据对象 | function | null |
onPulldown | 列表页面下拉回调,要求开发者主动提供更多数据,并刷新列表数据对象 | function | null |
onUpdateRow | 编辑页面回调,返回用户更新后的一条数据对象 | function | null |
onDeleteRow | 列表页面删除回调,返回被删除的数据id | function | null |
onClickRow | 列表页面点击一条数据的回调,返回被点击的数据id | function | 默认会进入单条数据详情页。如果有回调,则会替换默认行为 |
数据API
传入的数据,最终会被组件结合dataStruct定义来进行解析
内联属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
data | 组件实际维护的数据列表, 每一个数据项均以{key:value}表示,只支持number、bool、string基础类型 | array | [] |
框架数据标记规范
对任一条data数据,框架支持标准的框架标记
内联属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
axueMarking | 一个对象,标准字段如下 | array | [] |
notDelete | 表示该行不能删除 | bool | true |
status | 状态名 | string | null |
statusType | 状态类型,影响标识颜色: "nomal", 正常,显示为绿色"warning", 警告,显示为黄色"grey", 淡化,显示会灰色 | string | "nomal" |
扩展属性API
对于一行数据,省略号弹出,内置了删除、编辑两个功能菜单,如果不够,可以自定义扩展
内联属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
extendFunc | 扩展功能列表, 每一个功能均满足以下标准结构 | array | [] |
label | 菜单名 | string | "自定义功能" |
onClick | 点击回调,将传入rowdata数据 | function | null |
示例
JavaScript
/**
定义回调时,应该定义rowdata入参,组件会自动传入
注意,允许你在定义回调时,无入参,组件会照传,但不应该定义更多的参数,因为组件只会传入被点击的行数据
如果确实有多参数需求,请写在函数体内
*/
function onClick (rowdata){
console.log(rowdata)
}
特别说明
数据管理组件,需要特别注意的是数据规范和同步。
关于数据规范
传参机制:
- 允许服务端传冗余数据
- 对于新增页、编辑页、列表,要求定义可编辑、可显示范围
- 对于详情页字段,允许不定义,如果不定义,默认会显示该条数据的所有字段
- 正常不应该出现列表的各个数据长度不一致的情况
- 因为涉及了精准删除和性能考量,id索引字段是必须字段,且应该唯一。由于必须规则,即使定义了不填写索引字段,新增页也会自动生成一个临时的。这需要在收到回调后特别处理,完成替换。
- 更精细的行级控制,由组件的行级标记语法支持,比如禁止某一行被删除,强化状态或分类区分
关于数据同步
callback设计机制:
- 新增、更新、删除时,内存维护的data数据会第一时间更新,再回调通知开发者。
- 开发者应该在回调逻辑中,异步处理和读写存储服务层的同步
- 如果服务层处理异常,前端在异步逻辑的回调中,要重新处理边界,比如tips提醒用户、重置内存数据等
关于数据处理类型
dataType用于定义组件内部对一个数据的处理机制,代表了组件的业务支持能力范围,先从文本开始,逐渐上线。这也是一个通用规范,是label-content的一致规范,也是是label-*系列组件的适配范围设计基石。
说到底,数据组件的编辑能力建立在label-*系列组件之上。