前言
需求描述:微信小程序通过webview内嵌一个h5应用,h5应用中有一个扫码功能。
技术方案:通过调用微信小程序原生扫码功能实现。
具体步骤:在h5中点击扫码按钮,跳转到微信小程序的扫码页面,进入之后会立即扫码,拿到扫码结果后,跳转到小程序定义好的webview页面,在该页面跳转h5。
实现
微信小程序使用taro+vue3来实现。
小程序嵌入h5
在小程序中创建一个webview页面,通过设置web-view容器的src地址为h5地址,加载h5页面,这个容器会自动铺满整个小程序。
在小程序中创建一个扫码页面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说明文档
注意:需要先绑定一个微信公众号,并进向相应的配置后方可使用。