业务需求是需要使用扫码枪连续扫描,而且不允许手动输入,不允��直接粘贴。该需求前期已经通过antd的ProFormList实现了手动输入的操作。
1. 使用组件代码
使用组件如下:
js
<ProForm form={form}>
<ProFormList
name="seriesNoList"
initialValue={[{seriesNo: ""}]}
actionRef={actionRef}
>
{
(meta, index, action, count) => {
return (
<ProFormText
onChange={(e) => {}
name="seriesNo"
label="扫描商品编号"
placeholder="只能使用扫码枪"
/>
)
}
}
</ProFormList>
</ProForm>
2. 实现限制手动粘贴
第一反应在ProFormText
中监听onPaste事件。但是直接提示该组件没有该属性。然后往上找,ProFormList
上监听该事件是可以的。另外,继续往上找,ProForm
上也有该事件。所以在这两个组件上监听该事件都可以。
js
onPaste={(e) => {
e.preventDefault();
message.warning("不允许粘贴");
}}
3. 实现限制手动输入
通过onchange事件打印log可以知道,扫码枪的原理就是超快速的输入,并且最后输入一个keyCode == 13。其两个字符之间的时间间隔一般小于10ms。为了保险起见,临界值设成60。
js
{
(meta, index, action, count) => {
const arr = []; // 每个输入框一个记录数组
return (
<ProFormText
onChange={(e) => {
if (arr.length < 2) {
arr.push(e.timeStamp);
return;
}
if (arr[1] - arr[0] > 60) {
Modal.warn({
content: "只允许扫码枪输入",
afterClose: () => {
action.setCurrentRowData({seriesNo: ""})
}
});
arr.length = 0;
}
}}
name="seriesNo" label="扫描商品编号" placeholder="只能使用扫码枪" />
)
}
}
4. 实现扫码后自动新增聚焦
1. 实现自动新增
根据官方文档,自动新增有两种实现方式:
- 通过调用方法
js
actionRef.current?.add({
seriesNo: '新增' + list?.length,
});
- 手动点击最下方的新增按钮
因为想使用后续的onAfterAdd
事件,但是方法1不会触发该事件。所以只能通过手动触发。而自动新增需要监听到扫码枪的回车输入。即在ProFormList
中监听onKeyDown
事件,然后手动触发新增事件。
js
onKeyDown={(e) => {
if (e.keyCode === 13) {
e.preventDefault();
document.querySelector(".ant-pro-form-list-creator-button-bottom").click();
}
}}
2. 实现新输入框自动聚焦
因为要定位当前输入框是第几行,所以需要ProFormList的onAfterAdd
事件。因为该事件参数如下:
- defaultValue
- index
- count
其中index表示输入框的位置。然后手动实现聚焦。又因为立即去取最新的输入框dom取不到,所以通过setTimeout去取。
js
onAfterAdd={(text, index, count) => {
setTimeout(() => {
document.querySelector("#seriesNoList" + index + "seriesNo")?.focus();
})
}}