基于 ZXing 的 Vue 在线条形码扫描器实现

简介: 本文详解“在线条形码扫描器”的JavaScript实现:基于ZXing库,支持图片上传与实时摄像头扫描,统一管理状态、解码、结果归一化及一键复制,逻辑清晰、轻量易用。

这篇文章只讲本项目里“在线条形码扫描器”工具的功能 JavaScript 实现。它的目标很直接:让用户通过上传图片或调用摄像头,识别常见条形码内容,并把结果整理成可复制的文本。

在线工具网址:https://see-tool.com/barcode-scanner
工具截图:
工具截图.png

整个实现可以拆成 5 段:状态组织、扫描器初始化、图片识别、摄像头识别、结果整理与复制。

1)先围绕“扫描流程”组织状态

这个工具的前端状态不复杂,核心就是把一次扫描过程拆开管理:

  • activeTab:当前是图片上传还是摄像头扫描
  • fileInput:文件选择框引用
  • videoElement:摄像头视频元素引用
  • isCameraActive:摄像头是否已开启
  • results:扫描结果列表
  • copiedIndex:当前已复制的是哪一条结果
  • codeReader:条形码解码实例

这样做的好处是,上传、扫描、展示、复制这几段逻辑彼此独立,但都围绕同一份数据流运行。

2)扫描器实例只在浏览器端初始化

识别能力来自 @zxing/library 提供的 BrowserMultiFormatReader。页面挂载后再创建实例,页面卸载时顺手关闭摄像头。

let codeReader = null;

onMounted(() => {
   
  if (process.client) {
   
    codeReader = new BrowserMultiFormatReader();
  }
});

onUnmounted(() => {
   
  stopCamera();
});

这里的关键点不是“创建一个对象”,而是让识别器的生命周期和页面保持一致,避免用户离开页面后摄像头还占着。

3)图片识别是“文件 -> Base64 -> Image -> 解码结果”

上传和拖拽最终都会进入同一套处理逻辑。先判断文件是不是图片,再逐个读取。

const handleFiles = (files) => {
   
  if (!files || files.length === 0) return;

  Array.from(files).forEach((file) => {
   
    if (file.type.startsWith("image/")) {
   
      scanImageFile(file);
    }
  });
};

真正的识别过程分两步:

  1. FileReader 把本地图片读成 Data URL
  2. 创建 Image 对象,等图片加载完成后交给 ZXing 解码
const scanImageFile = (file) => {
   
  if (!codeReader) return;

  const reader = new FileReader();
  reader.onload = (e) => {
   
    const img = new Image();
    img.onload = () => {
   
      codeReader
        .decodeFromImageElement(img)
        .then((result) => {
   
          addResult(file.name, result.text, result.format);
        })
        .catch(() => {
   
          addResult(file.name, "未识别到条形码", "error");
        });
    };
    img.src = e.target.result;
  };
  reader.readAsDataURL(file);
};

这条链路的重点是:页面并不是直接“上传文件就扫”,而是先把文件转换成浏览器可处理的图像对象,再统一交给解码器。

4)摄像头识别是持续监听视频帧

和图片扫描一次不同,摄像头模式是持续从视频流中取帧,再不断尝试解码。

const startCamera = () => {
   
  if (!codeReader) return;
  isCameraActive.value = true;

  codeReader
    .decodeFromVideoDevice(null, videoElement.value, (result) => {
   
      if (result) {
   
        addResult("摄像头扫描", result.text, result.format);
      }
    })
    .catch(() => {
   
      isCameraActive.value = false;
    });
};

这里用了 decodeFromVideoDevice。它不是返回一次结果就结束,而是不断回调:

  • 当前帧识别到了条码,就立刻写入结果列表
  • 当前帧没识别到,就继续等下一帧

关闭摄像头时则统一调用重置方法:

const stopCamera = () => {
   
  if (codeReader) {
   
    codeReader.reset();
  }
  isCameraActive.value = false;
};

这样上传模式和摄像头模式可以随时切换,不会互相干扰。

5)结果要做一次归一化,方便展示和复制

解码器返回的原始结果里,最重要的是两部分:

  • text:条形码实际内容
  • format:条码格式

工具不会把原始对象直接丢给界面,而是先整理成统一结构:

const addResult = (source, content, format) => {
   
  const isError = format === "error";
  let formatName = format;

  if (!isError && typeof format === "number") {
   
    formatName = getFormatName(format);
  } else if (format && format.formatName) {
   
    formatName = format.formatName;
  }

  results.value.unshift({
   
    source,
    content,
    format: isError ? "" : String(formatName),
    isError,
  });
};

其中 getFormatName 的作用,是把数字格式码转换成更直观的名字,例如 CODE_128EAN_13UPC_A。这样用户看到结果时,不只是拿到内容,也能知道识别出的条码属于哪一类。

结果区还支持两个常用动作:

  • clearResults():清空历史结果
  • copyToClipboard():把指定结果复制到剪贴板
const copyToClipboard = async (text, index) => {
   
  await navigator.clipboard.writeText(text);
  copiedIndex.value = index;
  setTimeout(() => {
   
    copiedIndex.value = -1;
  }, 2000);
};

这段逻辑很轻,但很实用。对用户来说,识别完成不是终点,复制出去继续使用才是完整闭环。

6)这套功能 JS 的核心思路

这个工具的实现,本质上就是一条很清晰的数据链:

选择输入方式 -> 获取图片或视频帧 -> ZXing 解码 -> 统一整理结果 -> 复制或清空

从实现角度看,真正的重点不是界面,而是把“上传图片识别”和“摄像头实时识别”这两条路径收拢到同一套结果模型里。这样工具既容易维护,也能让普通用户用最少操作完成条形码识别。

目录
相关文章
|
18天前
|
机器学习/深度学习 存储 缓存
大模型架构算力对比:Decoder-only、Encoder-Decoder、MoE深度解析.71
本文深入解析三大主流大模型架构(Decoder-only、Encoder-Decoder、MoE)的算力消耗差异,聚焦注意力机制复杂度、参数量与计算密度三大维度。通过公式推导、代码模拟与可视化图表,揭示MoE稀疏激活的显著节算优势及瓶颈,剖析长文本场景下的“平方级算力黑洞”成因,并提供面向不同场景的架构选型建议。
346 20
|
1月前
|
人工智能 前端开发 JavaScript
拒绝“从零手搓”:计算机毕业生如何利用 AI 工具快速构建毕设原型?
面对 3 月中期检查压力,传统“手搓代码”模式已难以满足高效交付需求。本文对比了纯手写、外包与 AI 生成器三种开发模式,实测数据显示,利用 智码方舟 等 AI 辅助工具,可将全栈 Demo 搭建时间从平均 7 天缩短至 3 小时。文章详细拆解了 SpringBoot+Vue 项目快速落地 SOP,引用 Spring.io 官方架构建议,助你合规、高效完成毕设开发。
|
25天前
|
JavaScript
ASCII艺术字生成 在线工具分享
一款基于Vue开发的在线ASCII艺术字生成工具,无需安装,输入文字即可秒变个性艺术字。支持多字体、自定义宽度,适用于昵称、标题、文案等场景,操作极简,零门槛上手。
278 6
|
24天前
|
JavaScript 安全
短网址还原 在线工具分享
担心短链接藏风险?Vue开发的「短网址还原」在线工具,秒解真实地址、查看跳转路径、一键复制长链。无需安装,打开即用,助你安全查链、运营核验、资料整理更安心!
576 11
|
1月前
|
人工智能 开发工具 C++
LangGraph vs Semantic Kernel:状态图与内核插件的两条技术路线对比
本文对比2026年最新版LangGraph(v1.0)与Semantic Kernel(v1.28.1),澄清过时认知:LangGraph已成为LangChain执行引擎,支持持久化状态机;SK则原生集成MCP协议,定位AI中间件。二者架构迥异——图编排vs插件组合,运行时托管状态vs开发者自主管理。附代码实操与选型指南。
220 2
LangGraph vs Semantic Kernel:状态图与内核插件的两条技术路线对比
|
1月前
|
人工智能 Ubuntu API
告别Token烧钱!1分钟OpenClaw无技术阿里云/本地部署+免费大模型API配置,低成本养 AI 大虾及避坑指南
2026年,OpenClaw(昵称“大龙虾”)已成为开发者与办公人群的核心AI工具,但“Token消耗过快”始终是用户痛点——复杂任务单次调用可能消耗数千甚至上万Token,长期使用成本居高不下。而白山智算推出的新用户福利,为这一问题提供了高效解决方案:注册实名认证即送150元体验金,首次调用API再赠300元,累计450元可直接抵扣模型调用费用,支持MiniMax-M2.5、GLM-5、DeepSeek-V3.2等多款高性价比模型,且兼容OpenAI API格式,无需额外开发即可对接OpenClaw。
1117 7
|
1月前
|
Ubuntu 机器人 API
【保姆级教程】OpenClaw多Agent部署路由实战指南:全平台部署+飞书群绑定+阿里云百炼API配置指南
2026年,OpenClaw的多Agent协同能力已成为核心竞争力——通过创建不同角色的Agent(如办公助理、技术支持、数据分析师),可实现“专人专事”的高效协作。但多数用户在落地时遭遇两大痛点:一是“身份错位”,Agent在飞书群等渠道回复时身份混淆,消息未路由到对应Agent;二是“配置失效”,手动添加字段导致Gateway报错,整个路由规则瘫痪。
1795 8
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
构建AI智能体:九十、图解大模型核心三大件 — 输入编码、注意力机制与前馈网络层
本文深入解析了大模型三大核心技术:输入编码、多头自注意力机制和前馈网络层,从应用视角阐述了它们的工作原理和协同效应。输入编码负责将文本转换为富含语义和位置信息的数学表示;多头自注意力机制通过多专家团队模式建立全局依赖关系,解决长距离依赖问题;前馈网络层则通过非线性变换进行深度语义消歧。文章通过可视化示例展示了词向量的语义关系建模、注意力权重的分布模式以及前馈网络的语义过滤功能,形象地说明了大模型如何通过这三层架构实现"广泛联系-深度加工"的认知过程。
245 5
|
4月前
|
传感器 存储 人工智能
构建AI智能体:五十一、深思熟虑智能体:从BDI架构到认知推理的完整流程体系
本文系统介绍了深思熟虑智能体(Deliberative Agent)及其核心BDI架构。智能体通过信念(Beliefs)、愿望(Desires)、意图(Intentions)三个核心组件实现复杂决策:信念系统维护环境认知,愿望系统管理目标设定,意图系统执行行动计划。文章详细阐述了智能体的状态管理、推理机制和完整决策流程,并通过一个学术研究助手的设计示例,展示了如何实现从环境感知、计划制定到执行反思的完整认知循环。这种架构使智能体能够进行深度思考、规划和学习,而非简单反应式响应,代表了人工智能从工具性向认知性
524 5
|
27天前
|
机器学习/深度学习 数据采集 安全
大模型应用:联邦学习融合本地大模型:隐私合规推荐的核心流程与实践.62
本文探讨联邦学习与本地大模型(如Qwen1.5-1.8B)融合的推荐方案:在数据不出域前提下,通过加密参数协同训练,破解隐私合规与推荐精度的矛盾,实现“数据可用不可见”,已验证可显著提升稀疏数据门店的推荐准确率。
185 15

热门文章

最新文章

下一篇
开通oss服务