H5移动端页面实现快递单号条形码/二维码扫描,亲测可行!!

H5移动端页面实现快递单号条形码/二维码扫描,亲测可行!!
最新回答
盖世傻白甜

2026-01-31 21:47:06

在H5移动端页面实现快递单号条形码/二维码扫描功能,可以通过以下步骤完成:

  • 安装html5-qrcode库:

    npm install html5-qrcode
  • 页面代码实现:

    <template> <div class="registration-container"> <h2>快递登记</h2> <el-form label-position="top" :model="ruleForm" :rules="rules" ref="ruleFormRef"> <el-form-item label="真实退回快递单号" prop="expressNumber"> <el-input v-model="ruleForm.expressNumber" placeholder="请输入快递单号" clearable> <template #suffix> <SvgIcon @click="startScan" name="take-pictures" width="24" height="24" /> </template> </el-input> </el-form-item> <el-form-item label="快递公司" prop="expressCompany"> <el-input v-model="ruleForm.expressCompany" placeholder="请输入快递公司" clearable /> </el-form-item> </el-form> <div class="footer"> <el-button class="submit-btn" type="primary" style="width: 100%" @click="submitForm">提交</el-button> </div> </div> <!-- 全屏扫码层 --> <div v-if="scanning" class="scanner-container"> <div id="qr-reader" ref="qrReaderRef"></div> <p class="scan-hint">请将快递单条形码对准扫描框</p> <el-button class="close-btn" @click="stopScan">关闭</el-button> </div></template><script lang="ts" setup>import { ref, onUnmounted, reactive } from 'vue'import { Html5Qrcode } from 'html5-qrcode'import { type FormInstance, type FormRules, ElMessage } from 'element-plus'defineOptions({ name: 'after-sales-registration'})const ruleFormRef = ref<FormInstance>()const ruleForm = reactive({ expressNumber: '', expressCompany: ''})const rules = reactive<FormRules>({ expressNumber: [{ required: true, message: '请输入快递单号', trigger: 'blur' }], expressCompany: [{ required: true, message: '请输入快递公司', trigger: 'blur' }]})const scanning = ref(false)const qrReaderRef = ref(null)let html5QrCode: Html5Qrcode | null = null// 开始扫描const startScan = (event: Event) => { // 阻止事件冒泡和默认行为,防止输入框获得焦点 event.preventDefault() event.stopPropagation() if (scanning.value) return scanning.value = true // 如果有活动的输入框,尝试让它失去焦点 if (document.activeElement instanceof HTMLElement) { document.activeElement.blur() } // 延迟确保 DOM 渲染 setTimeout(() => { try { html5QrCode = new Html5Qrcode('qr-reader') const config = { fps: 10, qrbox: { width: 300, height: 100 }, // 横向长条,适合条形码 formats: [ 'code_128', // ? 快递单最常用 'code_39', // ? 部分快递使用 'ean_13' // ? 商品类快递 ] } html5QrCode .start( { facingMode: 'environment' }, // 后置摄像头 config, (decodedText) => { // console.log('?? 识别到快递单号:', decodedText) ruleForm.expressNumber = decodedText stopScan() // 自动关闭 }, () => {} ) .catch((err) => { ElMessage.error('摄像头启动失败:' + (err.message || '未知错误')) scanning.value = false stopScan() }) } catch (err) { ElMessage.error(`扫码库初始化失败,请重试${err}`) stopScan() } }, 300)}// 停止扫描const stopScan = () => { if (html5QrCode) { html5QrCode .stop() .then(() => { html5QrCode?.clear() html5QrCode = null scanning.value = false }) .catch(() => { // console.error('停止失败:', err) scanning.value = false }) } else { scanning.value = false }}const submitForm = () => { ruleFormRef.value?.validate((valid) => { if (valid) { // TODO:提交事件 } else { ElMessage.error('请填写完整信息') } })}// 组件卸载时确保关闭扫描onUnmounted(() => { if (html5QrCode) { html5QrCode.stop() }})</script><style lang="scss" scoped>.registration-container { width: 100%; height: 100%; padding: 20px; background: #f8f8fa; box-sizing: border-box; .footer { position: fixed; bottom: 0; left: 0; width: 100%; padding: 17px 0; text-align: center; box-shadow: 0px -4px 16px 0px rgba(60, 126, 254, 0.2); box-sizing: border-box; .submit-btn { width: 50% !important; background: #3c7efe; border-radius: 555px; } }}input { width: 100%; padding: 12px; margin: 10px 0; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; text-align: center; background-color: #f9f9f9;}button { width: 100%; padding: 12px; background-color: #d32f2f; color: white; border: none; border-radius: 6px; font-size: 16px; cursor: pointer;}button:disabled { background-color: #ef5350; cursor: not-allowed;}button:hover:not(:disabled) { background-color: #c62828;}/* 全屏扫码层 */.scanner-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: black; z-index: 9999; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding-top: 40px;}#qr-reader { width: 100%; max-width: 500px; border-radius: 12px; overflow: hidden;}.scan-hint { color: #4caf50; margin-top: 12px; font-size: 18px; font-weight: bold;}.close-btn { margin-top: 12px; padding: 8px 16px; background: #ff5252; color: white; border: none; border-radius: 4px; font-size: 14px;}</style>
  • 注意事项:

    必须HTTPS:生产环境必须部署在HTTPS域名下。

    用户授权:首次使用需用户允许摄像头权限。

    性能优化:避免在低性能设备上长时间运行。

    兼容性问题:在某些旧版浏览器可能不支持。

    移动端体验:html5-qrcode扫码体验一般,需要贴紧条形码。

  • 其他方案对比:

    html5-qrcode + 格式过滤:纯前端JS,轻量、易用、支持条形码,强烈推荐。

    ZXing JS(原生):纯前端JS,功能强大,但配置复杂,推荐。

    原生getUserMedia + QuaggaJS:纯前端JS,QuaggaJS已停止维护,可用但不推荐。

    调用微信JS-SDK扫码:依赖微信App,限微信环境。

    调用App原生能力(Hybrid):WebView + Native,高性能,需开发App。

    拍照上传 + 后端识别:前端 + 后端,稳定兜底,适合弱网或兼容性差的设备。

通过以上步骤和注意事项,可以在H5移动端页面实现快递单号条形码/二维码扫描功能。