扫码枪(扫描枪)扫码在vue中的使用教学

news2024/9/22 21:22:11

1.扫描枪使用原理浅析。

扫描枪的使用原理其实很简单:就是把光信号转换成电信号,再将电信号通过模拟数字转换器转化为数字信号传输到计算机中处理。其实可以简单理解为:二维码/条形码 转换成 字符串

2.扫描枪功能开发前准备。

正所谓“工欲善其事,必先利其器”,所以在准备开发此功能之前,我们得准备好两件事:

  • 扫描枪与主机的接入(扫描枪按接口分类通常有四种:SCSI接口EPP接口USB接口无线接口(蓝牙通讯),本文均以USB接口扫描枪vue项目中开发为例。)
  • 二维码/条形码(可用 草料官网 生成)。

3.扫描枪做了两件事。

  • 识别二维码/条形码的内容并填入input文本框中。
  • 自动执行键盘的回车事件。

4.核心代码与实例(单列)。

  • 图解(单列):

  • 核心代码(单列):
<el-table v-else :data="form.attrList" ref="newData" :height="tableHeight" key="pdlistbdk" border
                    tooltip-effect="dark" :header-cell-style="{ background: 'rgb(234,238,249)', color: '#333' }"
                    size="small">
                    <el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
                    <el-table-column :label="item.titleName" :prop="'title' + i" align="center"
                        v-for="(item, i) in headData2" :key="i">
                        <template slot-scope="scope">
                            <el-input :placeholder="'请输入' + item.titleName" ref="rowIndex2"
                                v-model="scope.row[scope.column.property]" style="width: 100%" size="mini" clearable
                                @change="changeVal(scope)"
                                @keydown.enter.native="nextFocus2(i + 1, scope.$index, scope.row[scope.column.property])" />
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" align="center" width="100">
                        <template slot-scope="scope">
                            <span v-if="scope.$index !== 0" class="g-table-btn" style="font-size:14px"
                                @click="delNewData2(scope.row, scope.$index)"><i class="icon iconfont icontrash"
                                    style="font-size:18px;color:#4574d0"></i>删除</span>
                        </template>
                    </el-table-column>
                </el-table>
                
                
data() {
        return {
            loading: false,
            tableHeight: '500',
            form: {
                attrList: [],    //最终用于提交的表格数据
            },
            //动态表头数据(单列)
            headData2: [
                {
                    titleName: "设备ID",
                    id: 1
                }
            ],
            allNum2: 0,    //总数(单列)
            rowIndex2: 0,  //行号(单列)
            attrIndex2: 1, //输入框列数(单列)
            delArr2: [],     //(单列)
        }
    },
    
    
    //新增行(单列)
        addRow2() {
            let query = {
                index: this.rowIndex2
            }
            //不存在attrList   新增该属性并新增一行
            if (!this.form.attrList) {
                this.$set(this.form, "attrList", [query]);
            } else {
                this.form.attrList.push(query);
            }
            //页面加载完成后再获取焦点
            this.$nextTick(() => {
                this.$refs["rowIndex2"][this.allNum2].focus();
                this.rowIndex2++
                this.allNum2 = this.attrIndex2 * this.rowIndex2
            })
        },
    
    //换行(单列),这里是因为实际项目会对每次扫码的内容做校验,所以加了接口。如果无需校验,直接执行res.code == 200内的代码即可。
        nextFocus2(index, row, val) {   //index为第几列(即为1);row为第几行(从0开始);val为当前文本框输入的值
            if (!val || !val.trim()) {
                this.$message({
                    message: '设备ID不能为空!',
                    type: 'warning',
                    showClose: true,
                });
                return false;
            }
            let data = new Object;
            data.out_store_no = this.scheindexId;
            data.device_id = val;
            //校验
            API.checkByScan(data)
                .then(res => {
                    if (res.code == 200) {
                        if ((row + 1) * this.attrIndex2 < this.allNum2 && this.allNum2 != 0) {
                            let val = this.attrIndex2 * row + index
                            this.$refs["rowIndex2"][val].focus();
                        } else {
                            //最后一个输入框跳转新增一行
                            if (index % this.attrIndex2 == 0) {
                                this.addRow2();
                                if ((row + 1) % 240 == 0) {  //是不是到了当前板的最后一行
                                    this.autoPrint();
                                }
                            } else {
                                let val = this.attrIndex2 * (this.rowIndex2 - 1) + index
                                this.$nextTick(() => {
                                    this.$refs["rowIndex2"][val].focus();
                                })
                            }
                        }
                    }
                })
                .catch(err => {

                })
        },
        
        //删除行(单列)
        delNewData2(row, index) {
            this.delArr2.push(row.index);
            this.form.attrList.splice(index, 1);
            this.rowIndex2--;
            this.allNum2 = this.attrIndex2 * this.rowIndex2;
            let delResult2 = this.form.attrList.length % 240;
            if (delResult2 == 0) {
                this.boardNum = this.boardNum - 1;
            }
        },
        
        //对每次扫码的数据进行处理,如无需额外处理,可去除。
        changeVal(e) {
            let curObj = e.row;
            let curIndex = e.$index;
            if (curObj.title0.includes('_')) {
                this.form.attrList[curIndex].title0 = curObj.title0.split('_')[1]
            } else {
                this.form.attrList[curIndex].title0 = curObj.title0;
            }
        },

5.核心代码与实例(多列)。

  • 图解(多列):

  • 核心代码(多列):
<el-table v-if="detailData.whether_card == 1" :data="form.attrList" ref="newData" :height="tableHeight"
                    key="pdlistdk" border tooltip-effect="dark"
                    :header-cell-style="{ background: 'rgb(234,238,249)', color: '#333' }" size="small">
                    <el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
                    <el-table-column :label="item.titleName" :prop="'title' + i" align="center"
                        v-for="(item, i) in headData" :key="i">
                        <template slot-scope="scope">
                            <el-input :placeholder="'请输入' + item.titleName" ref="rowIndex"
                                @change="changeVal(scope)"
                                v-model="scope.row[scope.column.property]" style="width: 100%" size="mini" clearable
                                @keydown.enter.native="nextFocus(i + 1, scope.$index, scope.row[scope.column.property])" />
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" align="center" width="100">
                        <template slot-scope="scope">
                            <span v-if="scope.$index !== 0" class="g-table-btn" style="font-size:14px"
                                @click="delNewData(scope.row, scope.$index)"><i class="icon iconfont icontrash"
                                    style="font-size:18px;color:#4574d0"></i>删除</span>
                        </template>
                    </el-table-column>
                </el-table>
                
                
     data() {
        return {
            loading: false,
            tableHeight: '500',
            form: {
                attrList: [],    //最终用于提交的表格数据
            },
            //动态表头数据(多列)
            headData: [
                {
                    titleName: "设备ID",
                    id: 1
                },
                {
                    titleName: "ICCID",
                    id: 2
                },
            ],
            allNum: 0,    //总数(多列)
            rowIndex: 0,  //行号(多列)
            attrIndex: 2, //输入框列数(多列)
            delArr: [],     //(多列)
        }
    },
    
    
    //对每次扫码的数据进行处理,如无需额外处理,可去除。
        changeVal(e) {
            let curObj = e.row;
            let curIndex = e.$index;
            if (curObj.title0.includes('_')) {
                this.form.attrList[curIndex].title0 = curObj.title0.split('_')[1]
            } else {
                this.form.attrList[curIndex].title0 = curObj.title0;
            }
        },
        
     //新增行(多列)
        addRow() {
            let query = {
                index: this.rowIndex
            }
            //不存在attrList   新增该属性并新增一行
            if (!this.form.attrList) {
                this.$set(this.form, "attrList", [query]);
            } else {
                this.form.attrList.push(query);
            }
            //页面加载完成后再获取焦点
            this.$nextTick(() => {
                this.$refs["rowIndex"][this.allNum].focus();
                this.rowIndex++
                this.allNum = this.attrIndex * this.rowIndex
            })
        },
        
        //换行(多列),这里是因为实际项目会对每次扫码的内容做校验,所以加了接口。如果无需校验,直接执行res.code == 200内的代码即可。
        nextFocus(index, row, val) {  //index为第几列(即为1和2);row为第几行(从0开始);val为当前文本框输入的值
            if (!val || !val.trim()) {
                this.$message({
                    message: index == 1 ? '设备ID不能为空!' : 'ICCID不能为空!',
                    type: 'warning',
                    showClose: true,
                });
                return false;
            }
            if (index == 1) {  //不做校验
                if ((row + 1) * this.attrIndex < this.allNum && this.allNum != 0) {
                    let val = this.attrIndex * row + index
                    this.$refs["rowIndex"][val].focus();
                } else {
                    //最后一个输入框跳转新增一行
                    if (index % this.attrIndex == 0) {
                        this.addRow()
                    } else {
                        let val = this.attrIndex * (this.rowIndex - 1) + index
                        this.$nextTick(() => {
                            this.$refs["rowIndex"][val].focus();
                        })
                    }
                }
            } else {  //校验
                let data = new Object;
                data.out_store_no = this.scheindexId;
                data.device_id = this.form.attrList[row].title0;
                data.iccid = this.form.attrList[row].title1;
                API.checkByScan(data)
                    .then(res => {
                        if (res.code == 200) {
                            if ((row + 1) * this.attrIndex < this.allNum && this.allNum != 0) {
                                let val = this.attrIndex * row + index
                                this.$refs["rowIndex"][val].focus();
                            } else {
                                //最后一个输入框跳转新增一行
                                if (index % this.attrIndex == 0) {
                                    this.addRow();
                                    if ((row + 1) % 120 == 0) {  //是不是到了当前板的最后一行
                                        this.autoPrint();
                                    }
                                } else {
                                    let val = this.attrIndex * (this.rowIndex - 1) + index
                                    this.$nextTick(() => {
                                        this.$refs["rowIndex"][val].focus();
                                    })
                                }
                            }
                        }
                    })
                    .catch(err => {

                    })
            }
        },
        
        //删除行(多列)
        delNewData(row, index) {
            this.delArr.push(row.index);
            this.form.attrList.splice(index, 1);
            this.rowIndex--;
            this.allNum = this.attrIndex * this.rowIndex;
            let delResult = this.form.attrList.length % 120;
            if (delResult == 0) {
                this.boardNum = this.boardNum - 1;
            }
        },

6.总结。

如图为例,最终的扫码录入数据都是保存在了form.attrList中。以上就是扫描枪在vue实际项目中的基本使用。特别需要注意的是如果我们在自己项目中需要对每次扫码录入的数据做特殊处理,一定不能直接对v-model绑定的数据做更改,会抛异常,而是应该借住input的change事件对其处理。(v-model的双向数据绑定原理可查看我的另一篇文章--v-mode的双向数据绑定原理解析与日常案例使用分析)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/659146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于【C语言】中scanf与getchar的用法和常见错误详解

写这篇博客的起因是最近博主自己学习中总是遇到类似的错误&#xff0c;并曾百思不得其解。 今天分享出来是希望帮助大家在写代码时避免这些错误。话不多说&#xff0c;我们直接开始吧&#xff01; 君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 输入函数scanf与getcha…

[架构之路-213]- 架构 - 架构设计过程快速概览与在线画图工具

目录 第一步&#xff1a;业务系统 &#xff08;1&#xff09;收集目标系统的用户需求 &#xff08;2&#xff09;定义用例图 第二步 领域建模 &#xff08;1&#xff09;业务流程定义 &#xff08;2&#xff09;业务功能分解 &#xff08;3&#xff09;非功能性架构&…

贝莱德出手了!

* * * 原创&#xff1a;刘教链 * * * 号外&#xff1a;今天在“刘教链Pro”发表了头条《内参&#xff1a;贝莱德向SEC申请的究竟是BTC信托还是现货ETF&#xff1f;信托和ETF的5点关键区别》&#xff0c;以及次条《私钥争夺战》&#xff0c;欢迎关注公众号“刘教链Pro”并阅读。…

mysql压缩包方式安装、data数据恢复

前言 最近电脑重装了系统&#xff0c;C盘彻底格式化了&#xff0c;但是D盘中的文件还是保留了下来。 我的MySQL的数据都在D盘了&#xff0c;想要重新恢复MySQL&#xff0c;还是很简单的&#xff1a; 重新安装Mysql将源数据拷贝到新的Mysql的data目录下 顺便记录一下MySQL压缩…

遥感数字图像处理教程复习整理

目录 01 说明 遥感影像的存储方式 BSQ方式 BIL方式 BIP方式 如何计算图像存储空间大小(字节数)&#xff1f; 简单的单位换算 计算公式 简单地 复杂地 如何查看影像的基本信息/辅助信息&#xff1f; 如何进行直方图的阈值分割&#xff1f; 辐射校正 系统辐射校正 …

SonarQube社区版安装插件实现扫描多分支

社区版不支持扫描多分支 社区版不支持扫描多分支&#xff0c;收费版才支持&#xff0c;开源社区有插件可以实现多分支的扫描 插件下载 点击此处跳转下载地址 我的SonarQube是安装的最新版本10&#xff0c;下载的插件版本也是最新的1.14.0&#xff0c;切记下载相对应支持的插件…

html学习与总结表单input系列标签

文章目录 表单标签input系列标签表单input总结button按钮标签select下拉菜单标签textarea文本域标签label标签 表单标签 input系列标签 标签属性说明inputtext文本框inputpassword密码框inputradio单选框inputcheckbok复选框 checked 默认选中inputfile文件上传 multiple 设置…

springboot整合spring-data-redis

前言 其实&#xff0c;整合是一个循序渐进的学习&#xff0c;你肯定是要了解之前底层的相关知识&#xff0c;才能够具体知道现在框架方法api到底tm有什么作用&#xff0c;所以建议先看看我之前的redis博客。 可以不看&#xff0c;但是可以以我这个为目录&#xff0c;针对性得…

python图像处理实战(二)—图像几何变换

&#x1f680;写在前面&#x1f680; &#x1f58a;个人主页&#xff1a;https://blog.csdn.net/m0_52051577?typeblog &#x1f381;欢迎各位大佬支持点赞收藏&#xff0c;三连必回&#xff01;&#xff01; &#x1f508;本人新开系列专栏—python图像处理 ❀愿每一个骤雨初…

Python接口自动化测试实战

目录 前言&#xff1a; 1.接口定义&#xff1a; 2.基本流程 3.需求分析 4.用例设计 5.脚本开发 5.3结果校验 6.结果分析 前言&#xff1a; Python是一款在自动化测试领域应用广泛的编程语言。通过使用Python的测试框架&#xff08;如unittest和pytest&#xff09;&…

【第一次】21级计科计算机组成原理课外练习

【第一次】21级计科计算机组成原理课外练习 一、判断题二、单选题三、多选题四、主观题 一、判断题 1-1 国防科技大学成功研制的“银河-II”通用并行巨型机的峰值速度超过同为国防科技大学研制的“天河一号”超级计算机。 错误 1-2 目前高端光刻机技术被荷兰ASML公司垄断&…

简要介绍 | 行人重识别 Person Re-identification

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对行人重识别进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 注2&#xff1a;“简要介绍"系列的所有创作均使用了AIGC工具辅助” 探索行人重识别技术&#xff1a;原理、挑战与未来展望 行人…

数字IC前端学习笔记:仲裁轮询(二)

相关文章 数字IC前端学习笔记&#xff1a;LSFR&#xff08;线性反馈移位寄存器&#xff09; 数字IC前端学习笔记&#xff1a;跨时钟域信号同步 数字IC前端学习笔记&#xff1a;信号同步和边沿检测 数字IC前端学习笔记&#xff1a;锁存器Latch的综合 数字IC前端学习笔记&am…

【代码阅读软件】VSCode最新版本 下载、安装、配置

目录 一、概述二、安装 VSCode 详细步骤三、基础配置3.1 安装中文插件3.2 安装其他插件 一、概述 VSCode 全称是 Visual Studio Code&#xff0c;是一款免费且开源的现代化代码编辑器&#xff0c;几乎支持所有主流开发语言的语法高亮、智能代码补全、代码片段提示、自定义快捷键…

(2023,网络修剪)探索 few-shot 图像生成中的不相容知识迁移

Exploring Incompatible Knowledge Transfer in Few-shot Image Generation 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 基础 4. FSIG 中不兼容的知识转移 4.1 调查不相容的知识 4.2 实验设置 4.3 结果和分析 5. 建议的方法 5.1 通过网络修剪进…

SpringCloud02:Eureka

什么是Eureka&#xff1f; 基于Restful的注册中心 Eureka基本的架构 Springcloud 封装了Netflix公司开发的Eureka模块来实现服务注册与发现 (对比Zookeeper).Eureka采用了C-S的架构设计&#xff0c;EurekaServer作为服务注册功能的服务器&#xff0c;他是服务注册中心.而系统…

React从入门到实战 -组件的三大核心属性(1)state

State state是组件对象最重要的属性&#xff0c;值是对象&#xff08;可以包含多个Key-value的组合&#xff09;组件被称为状态机&#xff0c;通过更新组件的state来更新对应的页面显示&#xff08;重新渲染组件&#xff09; class MyComponent extends React.Component {rend…

023.【回溯算法】

1. 回溯算法 回溯算法也叫试探法&#xff0c;它是一种系统地搜索问题而求解的方法。回溯算法可以找出所有解的一般性&#xff0c;同时可以避免不正确的数值。一旦发现不正确的数值&#xff0c;就不再继续下一层而是返回到上一层&#xff0c;以节省时间。简单来说&#xff0c;回…

OpenVino 2023.0学习使用(1)-简介

模型制备 每一个深度学习工作流程都是从获取模型开始的。您可以选择准备一个自定义的网络&#xff0c;使用现成的解决方案并根据您的需求进行调整&#xff0c;甚至可以从在线数据库下载并运行预先训练的网络&#xff0c;例如TensorFlow Hub&#xff0c;Hugging Face&#xff0…

C++入门:类和对象(中)

目录 前言&#xff1a; 一&#xff1a;类的6个默认成员函数 二&#xff1a;构造函数(第一个成员) (1)概念 (2)特性 (3)特性的解析 ⭐特性4 ⭐特性5 ⭐特性6 ⭐特性7 三&#xff1a;初始化列表 (1)引入 (2)概念 (3)注意 四&#xff1a;析构函数(第二个成员) …