微信小程序内嵌h5实现扫码功能

前言

需求描述:微信小程序通过webview内嵌一个h5应用,h5应用中有一个扫码功能。

技术方案:通过调用微信小程序原生扫码功能实现。

具体步骤:在h5中点击扫码按钮,跳转到微信小程序的扫码页面,进入之后会立即扫码,拿到扫码结果后,跳转到小程序定义好的webview页面,在该页面跳转h5。

实现

微信小程序使用taro+vue3来实现。

小程序嵌入h5

在小程序中创建一个webview页面,通过设置web-view容器的src地址为h5地址,加载h5页面,这个容器会自动铺满整个小程序。

微信小程序webview文档

在小程序中创建一个扫码页面webview/index

核心代码:

html 复制代码
<template>
  <view class="webview-container">
    <web-view
      v-if="src"
      :src="src"
      @message="onMessage"
      @load="onLoad"
      @error="onError"
    />
  </view>
</template>
<script setup lang="ts">
import { useRouter, useDidShow } from "@tarojs/taro";
const router = useRouter();

const src = ref("");

const onMessage = (e) => {
  console.log("webview-onMessage", e.detail.data);
};
const onLoad = (e) => {
  console.log("webview-onLoad", e.detail.src);
};
const onError = (e) => {
  console.log("webview-onError", e.detail.src);
};

const getURL = (url = "") => {
  let tempURL = decodeURIComponent(url);
  console.log("webview-url", url, " => ", tempURL);

  let infix = tempURL.indexOf("?") > -1 ? "&" : "?";
  let suffix = `orgCode=${parkCode.value}&terminal=${client.value}`;
  tempURL = tempURL + infix + suffix;

  src.value = tempURL;
};

useDidShow(() => {
  if (router.params.src) {
    getURL(router.params.src);
  }
});
</script>

h5唤起小程序原生扫码功能

点击扫码按钮,跳转到小程序内部的扫码页面,调用原生扫码接口,获取扫码结果后再进入到h5页面。

h5应用使用vue2来编写。

1、安装依赖

js 复制代码
npm install weixin-js-sdk --save
or
yarn add weixin-js-sdk --save

2、在需要扫码的页面引入

需要扫描的页面地址是:home/index.vue

核心代码:

html 复制代码
<template>
    <img class="scan" src="@/assets/images/scan.svg" @click="goScan" />
</tempate>

<script>
import wx from "weixin-js-sdk";
export default {
    methods: {
        // 扫一扫
        goScan() {
          if (navigator.userAgent.toLowerCase().indexOf("miniprogram") !== -1) {
            // 判断是否是微信环境
            wx.miniProgram.getEnv((res) => {
              if (res.miniprogram) {
                // 再次扫描后重置核销标志
                localStorage.setItem("complateScan", "0");
                // url为扫码成功后需要跳转的地址
                const url = window.location.href;

                // 小程序环境下逻辑,跳转到小程序的扫描页面地址(/pages/scan/index,自己定义的地址),可以带上页面返回时需要的参数
                wx.miniProgram.redirectTo({
                  url: `/pages/scan/index?url=${encodeURIComponent(url)}`,
                });
              } else {
                window.console.log(res, "res");
                this.$toast("非微信环境逻辑");
              }
            });
          } else {
            if (
              navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1
            ) {
              this.$toast("微信内置浏览器");
            } else this.$toast("非微信环境逻辑");
          }
        },
        
    }
}
</script>

3、小程序中的扫码页面

在小程序中创建一个扫码页面scan/index.vue,在这个页面中调用原生扫码接口,成功后跳转到h5页面

js 复制代码
<script setup lang="ts">
import Taro from "@tarojs/taro";
import { ref, onMounted } from "vue";
const router = useRouter();

const result = ref();

const goScan = () => {
  Taro.scanCode({
    onlyFromCamera: false,
    scanType: ["barCode", "qrCode", "datamatrix", "pdf417"],
    success: (res) => {

      result.value = JSON.stringify(res);
      goNext();
    },
    fail: (err) => {

      if (err && err.errMsg === "scanCode:fail cancel") {
        Taro.navigateBack();
      } else {
        result.value = JSON.stringify(err);
        goNext();
      }
    },
    complete: (val) => {
      console.log("scanCode-complete", val);
    },
  });
};
const goNext = () => {
  let url = router.params.url;
  if (url) {
    let tempURL = decodeURIComponent(url);
    console.log("scan-url", url, " => ", tempURL);

    let infix = tempURL.indexOf("?") > -1 ? "&" : "?";
    let suffix = `result=${result.value}`;
    tempURL = tempURL + infix + suffix;

    let src = encodeURIComponent(tempURL);
    Taro.redirectTo({
      url: `/pages/webview/index?src=${src}`,
    });
  } else {
    Taro.navigateBack();
  }
};

onMounted(() => {
  goScan();
});
</script>

4、扫码成功后跳转到h5扫码回调页面

由于业务需要,需要扫码的页面与扫码回调页面为同一个页面。

也就是需要在home页面监听地址栏是否有result参数,若有即扫码成功,再处理一些业务逻辑。

由于是同一个页面,我们需要定义一个complateScan标志,表示是否扫码过,只有扫码后未进行核销才去调取核销功能。

注意:扫码成功后重新打开这个页面,所以需要将该标志存储在localStorage中,不然在页面重新进入后数据丢失。

如步骤2同样页面

js 复制代码
<script>
export default {
    created() {
        // 是否核销过,1扫码后核销过,0扫码后未核销
        const complateScan = localStorage.getItem("complateScan");
        if (complateScan === "0") {
          // 获取传递回来的数据
          this.result = getLinkParams("result") || "";
          this.handleScanResult();
        }
    },
    methods: {
        
        // 处理扫描结果
        async handleScanResult() {
          if (this.result) {
            const obj = JSON.parse(this.result);
            // 表示已经核销过,下次在进入这个页面无需重复核销
            localStorage.setItem("complateScan", "1");

            // 扫码失败
            if (!obj.result) {
              this.$toast("扫码失败!");
            } else {
              // 扫码成功
              scanVerification({ content: obj.result })
                .then(() => {
                  this.$toast("签到成功!");
                })
                .catch(() => {
                  this.$toast("核销失败!");
                });
            }
          }
        },
    }
}
</script>

后记

在小程序中嵌入h5调用扫码功能,也可以使用微信提供的jssdk接口调取微信扫一扫。因为通过小程序webview容器嵌入的网页可以使用微信提供的jssdk接口。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

具体方法可以查看JS-SDK说明文档

注意:需要先绑定一个微信公众号,并进向相应的配置后方可使用。

相关推荐
北漂燕郊杨哥1 小时前
VS Code 安装微信小程序 MCP 介绍
vscode·微信小程序·小程序·mcp
维双云18 小时前
2026微信小程序开店用哪个平台?长期稳定运营的系统选择方法
微信小程序·小程序
辛迪聊物业数字化18 小时前
【智能楼宇系统有什么用?赋能园区高效 节能 安全】
经验分享·安全·微信小程序·php
Coodor1 天前
使用web也可以写NFC微信小程序拉取
前端·微信小程序·小程序·nfc拉起小程序
太阳之神aboluo2 天前
微信小程序 (1) 基础用法
微信小程序·小程序
黑马程序员毕设2 天前
基于B/S架构的“指尖乡味”助农电商小程序系统设计与实现
spring boot·微信小程序·小程序·架构·课程设计·毕设
编程小橘子3 天前
基于微信小程序健康心理测试、设计与实现 (源码+lw+参考文档+核心代码讲解等)
微信小程序·小程序·毕业设计·毕设
m0_462803883 天前
从产品逻辑看云分组「优先分组」如何实现培训会议按排自动分座
微信小程序
梓彤科技4 天前
登录状态总是失效,武汉小程序开发怎样设计会话续期与接口鉴权?
微信小程序·小程序·登录鉴权
黑马程序员毕设4 天前
非遗文化展览系统设计与实现
人工智能·spring boot·后端·微信小程序·毕设