1. 为什么要在uni-app H5里自己搞扫码?聊聊我的踩坑史
大家好,我是老张,一个在移动端开发里摸爬滚打了十来年的老码农。今天想和大家聊聊一个看似简单、实则暗藏玄机的功能:在uni-app的H5页面里实现扫码。
你可能要问了,现在手机不都有扫码功能吗?微信、支付宝一扫就行,干嘛要自己折腾?这话没错,但实际开发中,我们经常会遇到一些“特殊”场景。比如,你们公司的App是一个混合应用,壳子是原生的,但很多业务页面是用uni-app写的H5,嵌在WebView里跑。这时候,如果这个H5页面需要扫码,你总不能要求用户先退出你的页面,打开微信扫完,再手动把结果填回来吧?用户体验直接掉到谷底。
再比如,你们的产品可能运行在一些特定的硬件设备上,或者是一个企业内部的管理工具,需要在浏览器环境里直接调用摄像头完成扫码。这时候,一个纯前端、不依赖任何特定App的扫码方案就成了刚需。我当年就接过这么一个需求,要在一个运行在平板电脑浏览器里的库存管理系统中加入扫码入库功能,一开始也头大,试过各种方案,最后发现 html5-qrcode 这个库是真香。
所以,今天这篇实战指南,就是把我这几年在uni-app v2项目里集成 html5-qrcode 的经验、踩过的坑、优化的技巧,毫无保留地分享给你。无论你是刚接触uni-app的新手,还是正在为H5扫码头疼的老鸟,相信都能找到有用的东西。我们不扯那些高深的理论,就聊怎么把功能又快又稳地做出来。
2. 环境准备与项目初始化:万丈高楼平地起
在开始写代码之前,咱们得先把“灶台”搭好。这一步看似简单,但配置不对,后面全是坑。我见过不少新手在这一步就卡住了,不是环境变量不对,就是依赖装不上。
2.1 创建你的uni-app v2项目
首先,确保你本地已经安装了HBuilderX。这是uni-app的官方IDE,用起来比较顺手。如果你习惯用命令行,也可以用 vue-cli 的方式初始化,但为了减少环境问题,我强烈建议新手先用HBuilderX。
打开HBuilderX,点击「文件」->「新建」->「项目」。选择「uni-app」,填写项目名称,比如 uni-scan-demo,模板就用默认的「uni-app v2 项目模板」。记住,一定要选v2版本,因为v2和v3在部分API和生命周期上有些差异,咱们的代码是基于v2的。
项目创建好后,先别急着写代码。咱们得先明确一件事:我们这个扫码功能,主要是给 H5平台 用的。所以,在HBuilderX顶部菜单栏,把运行模式切换到「浏览器」。你会在左侧目录看到 manifest.json 文件,打开它,找到「H5配置」部分。这里有个关键点:确保你的项目运行在安全的上下文中(HTTPS或localhost)。因为现代浏览器出于安全考虑,只有在安全上下文中才允许访问摄像头。如果你用本地IP(比如192.168.x.x)调试,很多浏览器会直接禁止摄像头权限。最简单的办法就是用 localhost:8080 来运行调试。
2.2 引入html5-qrcode库的两种姿势
原始文章里提到了两种引入方式:npm安装和直接引入js文件。两种我都用过,各有优劣,我详细说说。
第一种:NPM安装(推荐给中大型项目) 这是最规范的方式,适合项目结构比较清晰、依赖管理严格的情况。打开你的项目根目录下的终端(HBuilderX内置了终端),执行:
npm install html5-qrcode --save
安装完成后,你可以在 package.json 的 dependencies 里看到它。这种方式的好处是版本管理方便,能和你的其他npm包一起更新。但有个小坑需要注意:html5-qrcode 这个库本身对ES模块的支持方式,可能会在uni-app的某些编译配置下遇到问题。如果你在引入后报错,可以尝试在 vue.config.js(如果没有就新建一个)里配置一下 transpileDependencies,把这个库加进去,让uni-app的编译过程也处理它。
第二种:直接引入CDN或本地JS文件(适合快速原型或简单项目) 这就是原始文章里用的方法,直接把库的 .min.js 文件下载下来,扔到项目的 static 目录里。你可以去 html5-qrcode 的GitHub仓库 releases 页面下载最新版的 html5-qrcode.min.js。 为什么这么做?有时候,npm安装可能会因为网络或依赖树问题卡住,直接引入文件就避开了所有包管理器的麻烦。而且,对于一些只需要在少数页面使用的功能,直接引入可以避免把整个库打包进全局的vendor.js,有助于减小主包体积。 具体操作:把下载好的 html5-qrcode.min.js 文件拷贝到项目 /static/js/ 目录下(没有就新建)。然后在需要使用扫码功能的页面,或者全局的 main.js 里,通过相对路径引入。不过我更推荐在页面组件内按需引入,这样更清晰。
两种方式没有绝对的好坏,我个人的习惯是:如果项目本身就用npm管理了很多包,那就用第一种;如果是小项目或者Demo,图个简单快捷,用第二种也没问题。今天我们的演示,会以第二种方式展开,因为它最直观,能让你清晰地看到每一步。
3. 手把手封装一个健壮的扫码组件
好了,基础打牢了,现在进入核心环节:封装扫码组件。原始文章给出了一个基础的组件代码,但那是骨架。在实际项目中,我们需要考虑更多:错误处理、用户体验、性能优化、兼容性等等。我来带你写一个更健壮、更实用的版本。
3.1 组件模板与样式:打造沉浸式扫描框
先看 template 部分。我们不仅要能扫,还要让用户扫得舒服。原始代码用了一个蒙层和居中框,这很好,但我们可以做得更细致。
<template>
<view v-if="visible" class="scan-container">
<!-- 顶部操作栏 -->
<view class="scan-header">
<text class="header-title">扫一扫</text>
<view class="close-btn" @tap="handleClose">×</view>
</view>
<!-- 核心扫描区域 -->
<view class="scan-main">
<view id="qr-reader" class="reader-wrapper"></view>
<!-- 增加一个扫描框的视觉引导 -->
<view class="scan-frame">
<view class="corner top-left"></view>
<view class="corner top-right"></view>
<view class="corner bottom-left"></view>
<view class="corner bottom-right"></view>

530

被折叠的 条评论
为什么被折叠?



