一、扫码枪的一些实现方法
在需求中经常会遇到扫码枪的需求,最大的难点在于,如何界定用户输入还是扫码枪输入。
1.输入速度检查
通过输入字符串的速度来确定是人为输入还是扫码枪输入,缺点是认为快速输入可能也会触发,可以限制文本长度,例如输入10个字符,用了20毫秒,来进一步确定是否为机器输入
2.约定扫描对象的结构
约定扫码获取的字符串,例如“[scanner] 100240000”,拼接约定的前缀或者后缀来实现判断
3.配置扫码枪
扫码枪一般官方提供了一些更改触发的方式,查阅官方说明
二、组件将采用第一种方式来实现一个扫码功能(并且可以在用户移出当前窗口后给予提示)
提示文字可以自己修改,或者改变文字提示的位置
2.1使用方式
<ScannerInput @scan="handleScan"></ScannerInput>
<script>
handleScan(scannedData) {
console.log('Scanned Data:', scannedData);
// 在这里处理扫描到的数据
}
</script>
2.2 组件源码
<!--
* @file: 扫码枪工具组件
-->
<!--
* @file: 扫码枪工具组件
-->
<template>
<div :style="computedStyle">
<el-tag v-if="!this.isPageFocused" type="danger"> {{ tipText }}</el-tag>
<!-- 空的div,不需要实际的输入元素 -->
<el-input style="position: absolute;top:-1000px" type="password" ref="scanInput" v-model="scanVal" @focus="inputFocus"></el-input>
</div>
</template>
<script>
export default {
name: 'ScannerInput',
props: {
// 输入字符间的最大时间间隔(毫秒),用于判断是否为扫码枪输入
maxInterval: {
type: Number,
default: 40,
},
// 扫码枪输入的最小长度
minLength: {
type: Number,
default: 8,
},
tipText: {
type: String,
default: '请聚焦到页面以进行扫码!!!!',
},
left: {
type: String,
default: '50%',
},
top: {
type: String,
default: '50px',
},
},
data() {
return {
scannerInput: '',
lastKeyPressTime: 0,
isPageFocused: true, // 页面聚焦状态
scanVal: '',
};
},
computed: {
computedStyle() {
return {
position: 'fixed',
left: this.left,
top: this.top,
zIndex: 999999,
transform: 'translate(-50%, -50%)',
timer: null,
};
},
},
methods: {
handleKeyPress(event) {
if (this.timer) {
clearTimeout(this.timer);
}
const currentTime = Date.now();
const timeDiff = currentTime - this.lastKeyPressTime;
this.lastKeyPressTime = currentTime;
// 正常处理扫码
// 根据时间间隔判断是否为扫码枪输入
if ((timeDiff < this.maxInterval || timeDiff === currentTime) && !event.ctrlKey) {
this.$refs.scanInput.focus();
this.scannerInput += event.key;
} else {
// 重置scannerInput,因为这可能是正常的键盘输入
this.scannerInput = event.key;
this.timer = setTimeout(() => {
this.lastKeyPressTime = 0;
}, 300);
}
// 检查扫码数据长度和结束字符
if (event.key === 'Enter' && this.scannerInput.length >= this.minLength) {
this.$emit('scan', this.scanVal);
this.scannerInput = '';
this.scanVal = '';
this.lastKeyPressTime = 0;
}
},
inputFocus() {
console.log('聚焦', 123);
},
handleWindowBlur() {
console.warn('请聚焦到页面以进行扫码');
this.isPageFocused = false;
this.$emit('pageBlur', !this.isPageFocused);
},
handleWindowFocus() {
this.lastKeyPressTime = 0;
this.isPageFocused = true;
this.$emit('pageBlur', !this.isPageFocused);
},
},
mounted() {
window.addEventListener('keydown', this.handleKeyPress);
window.addEventListener('blur', this.handleWindowBlur);
window.addEventListener('focus', this.handleWindowFocus);
},
beforeUnmount() {
console.log(234234);
window.removeEventListener('keydown', this.handleKeyPress);
window.removeEventListener('blur', this.handleWindowBlur);
window.removeEventListener('focus', this.handleWindowFocus);
},
};
</script>
<style lang="scss" scoped>
</style>