问题
由于扫描数据输入过快,会导致数据丢失情况
场景
自助机客户端插入硬件少扫描仪,需要扫描二维码或者条形码获取办件编号到input框
注意
扫描仪到输入过程中,通过控制键盘触发keyboardEvent事件,将数据输入到input框中,并在最后会触发一次Enter事件,所以最终我选择在input框的@keyup事件中对数据进行处理
方法一:
<template>
<div>
<!-- 阻止扫码枪的Enter事件自动提交el-form的提交特性 -->
<el-form @submit.native.prevent>
<el-form-item label="输入条码">
<el-input v-model="barcode" type="text" placeholder="输入条码" @keyup.native="handleKeyUp"></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
let barcodeVue = {
name: "Barcodescan",
data() {
return {
barcode: "",
realBarcode: "",
keyupLastTime: undefined,
};
},
methods: {
// 处理keyup事件
handleKeyUp(e) {
let gap = 0;
if (this.keyupLastTime) {
gap = new Date().getTime() - this.keyupLastTime;
if (gap > 50) {
gap = 0;
this.realBarcode = "";
}
}
this.keyupLastTime = new Date().getTime();
// 输入法会触发keyup事件,key为Process,跳过即可
if (e.key != "Process" && gap < 50) {
if (e.key.trim().length == 1) {
// 输入单个字母或者数字
this.realBarcode += e.key;
} else if (e.key.trim() == "Enter") {
// 根据规则,判断barcode类型,返回数据(自定义规则)
if (this.realBarcode) {
this.barcode = this.realBarcode;
this.realBarcode = "";
}else{
return;
}
}
}
}
}
};
export default { ...barcodeVue };
</script>
方法二:页面事件监听+输入时间间隔法
<template>
<div style="height:800px;width:800px;border:1px solid;padding:20px;margin:0 auto;margin-top:20px;">
<p style="text-align:center;">测试区域</p>
<barcodescan shopName="GZ1" @handle="handleBarcode"></barcodescan>
{{value}}
</div>
</template>
<script>
import Barcodescan from './components/Barcodescan'
export default {
name: 'Index',
components: {
Barcodescan
},
data() {
return {
value: undefined
}
},
methods: {
handleBarcode(barcodeMap) {
this.value = barcodeMap;
}
}
}
</script>
组件:
<template>
<div>
</div>
</template>
<script>
let barcodeVue = {
name: "Barcodescan",
props: {
shopName: {
type: String
}
},
data() {
return {
realBarcode: "",
keyupLastTime: undefined,
name: undefined,
regexRules: []
};
},
created() {
let that = this;
// 监听页面的keyup事件
document.onkeyup = function (e) {
that.handleKeyUp(e);
};
this.name = this.shopName;
this.initRegexRules();
},
methods: {
// 初始化条码规则(自定义)
initRegexRules() {
this.regexRules = [
{
regex: "/^IN(\\w|\\d)+$/",
value: "putInStorageNumber"
},
{
regex: "/^CH(\\w|\\d)+$/",
value: "checkNumber"
},
{
regex: "/^AL(\\w|\\d)+$/",
value: "allocateNumber"
},
{
regex: "/^\\d{12}$/",
value: "orderNumber"
},
{
regex: "/^SR(\\w|\\d)+$/",
value: "transferNumber"
},
{
regex: "/^\\d{12}-\\d{3}$/",
value: "sendNo"
},
{
regex: "/^PL\\d{10}$/",
value: "wavePickingNumber"
},
{
regex: "/^PL\\d{10}-\\d{3}$/",
value: "wavePickingGroupNumber"
},
{
regex: "/^(\\w|\\d)*-[\\w|\\d]*-\\d*-[A-Z]-\\d*/",
value: "location"
}
]
},
// 处理keyup事件
handleKeyUp(e) {
let gap = 0;
if (this.keyupLastTime) {
gap = new Date().getTime() - this.keyupLastTime;
if (gap > 50) {
gap = 0;
this.realBarcode = "";
}
}
this.keyupLastTime = new Date().getTime();
// 输入法会触发keyup事件,key为Process,跳过即可
if (e.key != "Process" && gap < 50) {
if (e.key.trim().length == 1) {
// 输入单个字母或者数字
this.realBarcode += e.key;
} else if (e.key.trim() == "Enter") {
// 根据规则,判断barcode类型,返回数据(自定义规则)
if (this.realBarcode) {
let data = {
type: this.barcodeRule(this.realBarcode),
code: this.realBarcode,
isLocal: this.isLocal(this.realBarcode)
};
this.$emit('handle',data);
this.realBarcode = "";
}
}
}
},
// 判断条码类型,如果没找到,则返回类型为barCode
barcodeRule(barcode) {
let value;
this.regexRules.some((item,index)=>{
let regex = eval(item.regex);
if(regex.test(barcode)){
value = item.value;
return true;
}
})
return value?value:"barCode";
},
// 根据条码是否包含门店名,判断是否本地条码
isLocal(barcode) {
return this.name?barcode.indexOf(this.name)!=-1:undefined;
}
},
};
export default { ...barcodeVue };
</script>