- A+
所属分类:Web前端
antd Pro组件ProFormList实现自定义action
ProFormList是ant design pro的结构化数据组件,通常用来实现动态表单。
现在有个需求,除了组件自带的删除和复制,还需要增加两个按钮来实现每个item位置的上下移动,如图所示:
查看官方文档,组件有提供自定义action的API--actionRender,介绍如下
/** * @name 自定义操作按钮 * * @example 删除按钮 * actionRender:(field,action)=><a onClick={()=>action.remove(field.name)}>删除</a> * @example 最多只能新增三行 * actionRender:(f,action,_,count)=><a onClick={()=> * count>2?alert("最多三行!"):action.add({id:"xx"})}>删除 * </a> */ actionRender?: ( field: FormListFieldData, /** * 操作能力 * @example action.add(data) 新增一行 * @example action.remove(index) 删除一行 * @example action.move(formIndex,targetIndex) 移动一行 */ action: FormListOperation, /** * 默认的操作dom * [复制,删除] */ defaultActionDom: ReactNode[], /** * 当前共有几个列表项 */ count: number, ) => ReactNode[];
API提供的参数--action提供了移动位置的方法action.move(formIndex,targetIndex),只需要传入当前位置索引和目标位置索引即可。
那现在的问题就是如何知道当前操作的item索引位置呢,官方文档写的不是很详细。研究了一会,奥秘竟在field参数中!
打印一下三个item的field
{ "name": 0, "key": 0, "isListField": true, "fieldKey": 0, "uuid": "fbf3b67a-345b-4645-ad0e-5bef325a8c39" } { "name": 1, "key": 1, "isListField": true, "fieldKey": 1, "uuid": "2f8a7f5a-34f2-456e-8816-6ab0b6e72332" } { "name": 2, "key": 2, "isListField": true, "fieldKey": 2, "uuid": "926653b6-df29-447a-bd40-a16a178e251a" }
尝试执行move(0,1)后,再次打印对比uuid发现,name的值正是list索引,且随数组动态变化的,那就好办了,你早说嘛真是的。
于是答案呼之欲出:
actionRender={(field, action, defaultActionDom, count) => { return [ ...defaultActionDom, <ArrowUpOutlined key="up_arrow" style={{ marginLeft: '5px' }} onClick={() => { if (field.name === 0) { //位于第一个,移动到最后一个 action.move(field.name, count - 1); } else { action.move(field.name, field.name - 1); } }} />, <ArrowDownOutlined key="down_arrow" style={{ marginLeft: '5px' }} onClick={() => { if (field.name === count - 1) { //位于最后一个,移动到第一个 action.move(field.name, 0); } else { action.move(field.name, field.name + 1); } }} />, ]; }}
defaultActionDom直接挪过来,增加判断:当item位于第一个时向上移动到最后一个,位于最后一个时向下移动到第一个,搞定