PDA手持终端扫码器概述
- PDA扫描枪(又称棒枪、手持终端、手持数据采集器等)是一种将PDA(掌上电脑)与扫描器结合在一起的扫码器,提高了使用的方便性与工作效率,节约了成本,在销售行业、物流行业使用广泛。
- 我们可以简单理解为有扫码功能的手机(安卓)。这样理解之后,我们在PDA扫码器上进行软件开发,其实就是开发安卓app。
- 而作为一个前端,开发app我们主要用的框架是uniapp,本篇文章将介绍如何使用uniapp来开发一个扫码app
uniapp实现扫码app
PDA扫码有两种模式:广播模式和键盘模式,这里我用比较简单的键盘模式(即使用输入框接收扫码数据)
需求
- app使用
input 接收扫码枪扫出来的数据,将扫出来的数据显示在页面上; - 可连续扫码,扫码过程中不出现软键盘(输入法)。
原理
- 在键盘输出模式下,扫码枪会将获取的内容赋值在获取焦点的
input 上 (扫到东西的话会自动在焦点处输出)。 - 扫码后会自动触发
@confirm 回车事件,通过v-model 数据绑定获取到扫码数据。
实现
1. input输入框获取扫码内容
以下就是最简单的接收扫码数据的实现方法:
<template> <view> <input type="text" auto-focus="true" v-model="scanValue" placeholder="扫一扫二维码" /> </view> </template> <script> export default { data() { return { scanValue:"", } }, methods: { } } </script> <style> input{ border: 1rpx solid #ccc; margin: 40rpx 20rpx; padding: 15rpx; border-radius: 10rpx; } </style>
我们可以去用一些二维码生成工具(如草料二维码),生成一些二维码试一下
成功拿到数据~
没错,就是这么简简单单,一个
2. @confirm扫码触发事件
给
<input @confirm="getScanValue" type="text" auto-focus="true" v-model="scanValue" placeholder="扫一扫二维码" />
// 扫码后触发的事件 getScanValue(){ console.log(this.scanValue); // 扫码成功的一些操作,比如用扫码数据作为参数请求后端接口 }
3.将扫码结果显示在页面上,自动聚焦
- 我们可以将扫码到的结果显示在页面上,每次回车就把它加到页面上并清空上一次获取到的数据。
- 这里会有一个问题,就是我们每次
push 后清空数据,输入框会失焦,下一次要扫码必须手动点一下输入框聚焦才能继续接收扫码数据,这样使用体验肯定是不好的,所以我们每次清空数据后,需要自动聚焦。 - 我们可以用
:focus="focus" 动态绑定焦点,失焦的时候聚焦。
<input @confirm="getScanValue" type="text" auto-focus="true" v-model="scanValue" placeholder="扫一扫二维码" :focus="focus" /> <view class="item" v-for="(item,index) in results" :key="index"> <text class="index">{{index+1}}</text> <text>扫码数据:{{item}}</text> </view>
poinblur() { this.focus = false; this.$nextTick(() => { this.focus = true; }) }, // 扫码后触发的事件 getScanValue() { // 扫码成功的一些操作,比如用扫码数据作为参数请求后端接口 console.log(this.scanValue); this.results.push(this.scanValue); this.scanValue = ''; // push后清空 this.poinblur();// 自动聚焦 }
- 这里我还想过给
input 绑定@blur="poinblur" ,在失焦的时候就自动聚焦,但是它在真机情况下,会出现焦点频繁跳动的情况,所以还是手动调this.poinblur() 比较好
真机调试
我们可以一边写代码一边使用,不知道如何真机调试的请看完这篇:
手机连接电脑方法,uni-app安卓真机调试教程,安卓手机调试
出现的bug解决方法
1. 无法获取扫码数据,@confirm不触发
一定要确保输入框是聚焦的!!有焦点才可以进行获取数据触发事件,如果某个事件执行后失焦,只要
// 聚焦 poinblur() { this.focus = false this.$nextTick(() => { this.focus = true; }) },
还有一个就是要在PDA机设置!!在扫描设置里,把模拟键回车勾上,这个设置由于机型不一样可能叫法不一样,有的叫发送Enter键的
2. 加载页面后一会,焦点消失
加载/显示页面的时候自动聚焦即可(一定要加上定时器,不然无效)
onShow(){ setTimeout(()=>{ this.poinblur() },500) },
3. 连续扫码,聚焦弹软键盘问题
- 扫码枪每次聚焦操作都会引起页面弹出软键盘(输入法),这个软键盘会遮挡一部分页面,而且弹出弹下很影响用户观感,必须得把这个去掉。
- 这个问题我也试过网上的很多方法,比如
uni.hideKeyboard() (会有软键盘频繁闪动的bug),给input 加disabled 或者readonly (无效),还是无法解决。 - 最后发现是要在PDA里面的扫描设置,配置键盘映射或者禁用输入法、软键盘。
- 键盘映射是我觉得最完美的解决方法了,只要给某个键设置软键盘的功能,就可以显示隐藏软键盘了,也不会有bug
完整代码
<template> <view> <input @confirm="getScanValue" type="text" auto-focus="true" v-model="scanValue" placeholder="扫一扫二维码" :focus="focus" /> <view class="item" v-for="(item,index) in results" :key="index"> <text class="index">{{index+1}}</text> <text>扫码数据:{{item}}</text> </view> </view> </template> <script> export default { data() { return { scanValue: "", focus: true, // 输入框焦点 results: [],// 扫码结果 } }, methods: { // 自动聚焦 poinblur() { this.focus = false; this.$nextTick(() => { this.focus = true; }) }, // 扫码后触发的事件 getScanValue() { console.log(this.scanValue); this.results.push(this.scanValue); this.scanValue = ''; // push后清空 this.poinblur();// 自动聚焦 } } } </script> <style> input { border: 1rpx solid #ccc; margin: 40rpx 20rpx; padding: 15rpx; border-radius: 10rpx; } .item{ margin: 20rpx; padding: 20rpx; } .item .index{ border: 1rpx solid #333; padding: 5rpx 10rpx; margin-right: 15rpx; } </style>