众所周知,uniapp的H5端没有封装扫码功能,如果你的项目需要运行在H5端、微信H5端等,就需要自己实现扫码功能

(微信H5其实可以调用wx.config注册扫码功能,然后就能使用微信的扫一扫了,本插件可以在不config注册的前提下扫码,但实现效果肯定不如微信的扫一扫)

今天在这里直接放上一个H5可用的扫码组件,基于 html5-qrcode 封装

组件已上传至uniapp插件市场,免费下载使用:

https://ext.dcloud.net.cn/plugin?id=25657

本文目录

先看实现效果

扫码组件代码

页面引入使用

示例项目 / 下载代码

注意事项


先看实现效果

扫码组件代码

这是扫码组件代码,新建vue文件,放在 components 目录下即可

<template>
  <view class="easy-scancode" v-if="show">
    <view id="reader"></view>
    <!-- 扫码提示区域 -->
    <view class="scan-tip-overlay">
      <view class="scan-tip"> 请将二维码放入框内 </view>
    </view>
  </view>
</template>

<script>
import { Html5Qrcode } from "html5-qrcode";
export default {
  name: "easy-scancode",
  data() {
    return {
      options: {
        success: () => {},
        fail: () => {},
      },
      show: false,
      html5QrCode: null,
    };
  },
  methods: {
    start(options) {
      this.options = options;
      // #ifdef H5
      // 检查摄像头权限
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices
          .getUserMedia({
            video: true,
          })
          .then((stream) => {
            // 获得权限后关闭流
            stream.getTracks().forEach((track) => track.stop());
            this.show = true;
            // 有权限后调用扫码
            this.getCameras();
          })
          .catch((err) => {
            // 用户拒绝了权限
            uni.showToast({
              title: "请允许使用摄像头权限!",
              icon: "none",
            });
            this.options.fail("未获得摄像头权限");
          });
      } else {
        uni.showToast({
          title: "您的浏览器不支持访问摄像头",
          icon: "none",
        });
        this.options.fail("浏览器不支持访问摄像头");
      }
      return;
      // #endif
      // 其他环境
      uni.scanCode({
        onlyFromCamera: true,
        success: (res) => {
          this.options.success(res.result, res);
        },
        fail: (rej) => {
          this.options.fail("扫码失败");
        },
      });
    },
    stop() {
      this.show = false;
      let that = this;
      this.html5QrCode
        .stop()
        .then((ignore) => {
          // 二维码扫描已停止
          console.log("二维码扫描已停止");
        })
        .catch((err) => {
          // 停止失败,处理错误
          console.log("无法停止扫描");
        });
    },
    getCameras() {
      let that = this;
      Html5Qrcode.getCameras()
        .then((devices) => {
          // console.log(devices)
          that.html5QrCode = new Html5Qrcode("reader");

          let windowInfo = uni.getWindowInfo();
          console.log(windowInfo);
          const width = windowInfo.windowWidth;
          const height = windowInfo.windowHeight;
          // 横屏
          const aspectRatio = width / height;
          // 竖屏
          const reverseAspectRatio = height / width;

          const mobileAspectRatio =
            reverseAspectRatio > 1.5
              ? reverseAspectRatio + (reverseAspectRatio * 12) / 100
              : reverseAspectRatio;

          if (devices && devices.length) {
            let cameraId = "";
            if (devices.length > 1) {
              cameraId = devices[1].id;
            } else {
              cameraId = devices[0].id;
            }
            // 计算二维码扫描框大小 - 使用宽度/高度中较小的值来确保方框适合屏幕
            // 并在扫描区域周围留出一些边距
            const qrboxSize = Math.min(width, height) * 0.7;
            console.log(qrboxSize);
            // 使用这个来开始扫描
            that.html5QrCode
              .start(
                {
                  facingMode: "environment",
                },
                {
                  fps: 10, // 可选,二维码扫描的每秒帧数
                  aspectRatio: aspectRatio,
                  qrbox: { width: qrboxSize, height: qrboxSize }, // 可选,如果你想要边界框UI
                  videoConstraints: {
                    facingMode: "environment",
                    aspectRatio: width < 600 ? mobileAspectRatio : aspectRatio,
                  },
                },
                (decodedText, decodedResult) => {
                  // 当码被读取时执行操作
                  console.log("decodedText", decodedText);
                  that.options.success(decodedText, decodedResult);
                  that.stop();
                },
                (errorMessage) => {
                  // 解析错误,忽略它
                  // console.log('解析错误,忽略它', errorMessage)
                }
              )
              .catch((err) => {
                // 启动失败,处理它
                console.log("启动失败,需要处理");
                that.options.fail(err);
                this.show = false;
              });
          }
        })
        .catch((err) => {
          // 处理错误
          console.log(err);
          that.options.fail(err);
          this.show = false;
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.easy-scancode {
  width: 100vw;
  height: 100vh;
  position: fixed;
  z-index: 1000;
  top: 0;
  left: 0;
  background-color: #000;
}

#reader {
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}

.scan-tip-overlay {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 10000;
	pointer-events: none; /* 不阻挡摄像头画面 */
}

.scan-tip {
	position: absolute;
	top: 74%;
	left: 50%;
	transform: translateX(-50%);
	color: #fff;
	font-size: 16px;
	text-align: center;
	z-index: 10001;
	background-color: rgba(0, 0, 0, 0.5);
	padding: 10px 20px;
	border-radius: 5px;
}
</style>

页面引入使用

<template>
	<view class="content">
		<button @click="start">开始扫码</button>
		<!-- 扫码组件 -->
		<scan-code ref="scan"></scan-code>
	</view>
</template>

<script>
	import scanCode from '@/components/easy-scancode/easy-scancode.vue'
	export default {
		components: {
			scanCode
		},
		data() {
			return {
			}
		},
		methods: {
			start() {
				this.$refs.scan.start({
					success: (val, res)=> {
						console.log('扫描成功',val,res)
					},
					fail: (rej)=>{
						console.log('扫描失败',rej)
					}
				})
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

</style>

示例项目 / 下载代码

 组件已上传至uniapp插件市场,免费下载组件代码 及 示例项目

https://ext.dcloud.net.cn/plugin?id=25657

注意事项

1. 本组件基于 html5-qrcode 封装,理论支持所有H5环境;

2. 本组件基于 uniapp 开发,其他框架请自行修改代码;

3. 本组件已对多端进行兼容,编译到 小程序、APP端时,调用 start 扫码方法时会自动使用其他环境提供的扫码功能,如小程序会调用微信的扫一扫、APP调用系统的扫码功能;

4. 没了;

更多推荐