微信外H5跳转小程序——组件(vue项目)

场景
有个H5(vue项目),需要实现点击商品item跳转到小程序,微信内和微信外都要支持,这里我们只介绍一下H5在微信外的跳转。
如图所示,红框内是一个商品,就是点击这里,要跳转小程序:
微信外H5跳转小程序——组件(vue项目)
文章图片

配置微信小程序云开发(云函数)
1、开通云开发
微信外H5跳转小程序——组件(vue项目)
文章图片

然后选择免费额度
2、云开发权限设置
微信外H5跳转小程序——组件(vue项目)
文章图片

找到权限设置,把这里的「未登录用户访问权限」点开
3、新建云函数openMiniapp
微信外H5跳转小程序——组件(vue项目)
文章图片

这里我们先只需要建个名为openMiniapp的云函数放在这里就行,它的代码后面再写。
4、修改云函数权限
微信外H5跳转小程序——组件(vue项目)
文章图片

添加一下这部分配置,注意这里的名称要和云函数的名称一致:
微信外H5跳转小程序——组件(vue项目)
文章图片

云函数代码
1、编写云函数代码
如果是原生小程序,当配置完云开发+云函数之后,小程序项目目录应该就多出一个云函数的目录(可能叫cloudbase,但是因为我这里是用的uniapp,这个目录是自定义的,我设置为wxcloudfunctions):
微信外H5跳转小程序——组件(vue项目)
文章图片

附:
uniapp配置云函数教程1
uniapp配置云函数教程2
云函数的代码:

package.json:{ "name": "GENERAL", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "wx-server-sdk": "~2.3.2" } } 复制代码

index.js:
const cloud = require('wx-server-sdk') cloud.init()exports.main = async (event, context) => { const { path = '', queryData = https://www.it610.com/article/{}, } = event // 我从H5那边传进来的参数,可以从event里获取到// 获取queryStr let queryStrArr = [] for (let key in queryData) { const str = `${key}=${queryData[key]}` // name=tom queryStrArr.push(str) } const queryStr = queryStrArr.join('&')console.log('path', path) console.log('queryStr', queryStr)return cloud.openapi.urlscheme.generate({ jumpWxa: { path: path ? ('/' + path) : '', // 打开小程序时访问路径,为空则会进入主页 query: queryStr, // 可以使用 event 传入的数据制作特定参数,无需求则为空 }, isExpire: true, //是否到期失效,如果为true需要填写到期时间,默认false expire_time: Math.round(new Date().getTime() / 1000) + 3600 //我们设置为当前时间3600秒后,也就是1小时后失效 //无需求可以去掉这两个参数(isExpire,expire_time) }) }复制代码

2、部署云函数
右键,选择创建并部署。
微信外H5跳转小程序——组件(vue项目)
文章图片

这样云函数的部署就完成了。
H5部分
1、
我的想法是写一个通用组件,不包含任何样式,内容通过传进来,这样后面不管什么样的跳转都可以使用它了。
我可以这样:
{{ item.goodsName }} {{ item.goodsFeeStr }}元 {{ item.goodsDesc }} 复制代码

也可以这样:
复制代码

2、介绍props
微信外H5跳转小程序——组件(vue项目)
文章图片

附:
云环境id的位置:
微信外H5跳转小程序——组件(vue项目)
文章图片

3、关键代码
配置H5的云函数 init
methods: { ... // 先配置 async preConfig() { const self = this if (isWeixin()) { // 这里先忽略,这是 微信内H5 配置wxjssdk的部分 return await configWx([], ['wx-open-launch-weapp']) } else { // 微信外 if (!window.tcb) { window.tcb = new window.cloud.Cloud({ identityless: true, resourceAppid: self.appid, resourceEnv: self.envid, }) } return await window.tcb.init() } }, ... } 复制代码

window.jumpAppState
因为有时一个页面里,可能会有多个,比如一个需要跳转小程序的商品列表,每个商品item都要包裹一个
而云函数其实只需要初始化一次,因为云函数是挂到window上的。即使是微信内的H5,每个页面wx jssdk也只需要初始化一次。
所以这里增加了个window.jumpAppState的变量用来判断当前页面是否正在初始化和是否初始化完成,用window.location.hash作为key,用来区分不同的页面。
async mounted() { console.log('jumpApp mounted') if (!window.jumpAppState) window.jumpAppState = {}// console.log(window.jumpAppState[`isReady_${window.location.hash}`]) // console.log(window.jumpAppState[`isGettingReady_${window.location.hash}`]) // 先配置 if (!window.jumpAppState[`isReady_${window.location.hash}`] && !window.jumpAppState[`isGettingReady_${window.location.hash}`]) { console.log('进入配置') window.jumpAppState[`isGettingReady_${window.location.hash}`] = true await this.preConfig() window.jumpAppState[`isGettingReady_${window.location.hash}`] = false window.jumpAppState[`isReady_${window.location.hash}`] } // 先配置 endconsole.log('配置完毕')this.isPreConfigFinish = true }, 复制代码

调用云函数openMiniapp,拿到openLink
methods: { ... // 微信外 async initOutWeixin() { const self = this let res try { res = await window.tcb.callFunction({ name: self.callFunctionName, // 提供UrlScheme服务的云函数名称 data: { path: self.path, queryData: self.queryData, }, }) } catch (e) { console.log('云函数失败了', e) } console.log('云函数结果', res) this.minihref = https://www.it610.com/article/res?.result?.openlink ??'' this.isInitWechatFinish = true }, // 微信外跳转小程序 click handleOutWeixinClick() { if (!isWeixin() && this.minihref && this.isInitWechatFinish) { window.location.href = https://www.it610.com/article/this.minihref } }, ... } 复制代码

我设置的几个变量 isPreConfigFinish isCanInitWechat isInitWechatFinish
· isPreConfigFinish
代表window.tcb是否init完成(如果是微信内的话,代表wx jssdk是否config完成)
· isCanInitWechat
是否preConfig完成,同时外部的一些参数是否准备好了。
因为有时我们跳转时携带的参数是异步获取的,比如订单号、商品code等,所以设置了一个props.ready的变量。
只有当isPreConfigFinish已经为true,且一些异步的数据已经拿到即props.ready为true的时候,isCanInitWechat为true
· isInitWechatFinish
代表云函数调用成功了,拿到了openLink(微信内的话,就是wxjssdk config成功,并且已经加到了html里)
最终拿到的这个minihref就是类似这种的地址:"weixin://dl/business/?ticket=slejlsdjlf",我们直接调用window.location.href = https://www.it610.com/article/this.minihref 就能触发跳转小程序了。
ok 这样就开发完成了
完整代码
.p_1646876870010 { position: relative; overflow: hidden; .open_app_div { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } }复制代码

附上微信内H5配置wxjssdk的代码configWx
/** * @param {Array} jsApiArr * @returns */ export function configWx(jsApiArr = [], openTagArr = []) { return new Promise(async (resolve, reject) => { if (!wx) return reject()wx.ready(function (res) { // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 console.log('wx ready 我打印的', res) return resolve() })wx.error(function (err) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 console.log('wx error 我打印的', err) return reject(err) })// 请求 let config = null try { /** * 苹果分享会是调取签名失败是因为:苹果在微信中浏览器机制和安卓不同,有IOS缓存问题,和IOS对单页面的优化问题, * 通俗点说安卓进行页面跳转分享时会刷新当前的url,而苹果不会,苹果是通过历史记录进来的,不会刷新url所以会导致签名失败)。 * * 所以 * 获取signUrl 安卓传全部的href,ios只用传#之前的 */ let signUrl = '' if (isIOS()) { signUrl = window.location.href.split('#')[0] } else { signUrl = window.location.href } const res = await request({ url: '/h5/user/jsapi/initConfig', data: { url: signUrl }, }) config = res?.data ?? {} } catch (error) { return reject(error) } if (config) { wx.config({ // debug: getIsProd() ? false : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 debug: false, appId: appid + '', timestamp: config.timestamp + '', // 必填,生成签名的时间戳 nonceStr: config.nonceStr + '', // 必填,生成签名的随机串 signature: config.signature + '', // 必填,签名 jsApiList: ['hideMenuItems', ...jsApiArr], // 必填,需要使用的JS接口列表 // 这个貌似不能空 openTagList: [...openTagArr], }) } }) }

最后
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑
如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !
【微信外H5跳转小程序——组件(vue项目)】PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com

    推荐阅读