上个月, 小程序开放了新功能, 支持内嵌网页, 所以我就开始了小程序内嵌网页之路, 之前我只是个小安卓
小程序 webview.PNG
内嵌网页中可使用 JSSDK 1.3.0 提供的接口, 可坑就来了, 居然不支持支付接口的调用, 经过一番研究, 总算打通了两边的交互
大概流程
先说明涉及到的文件, 下面会用到
1.1 app.js: 小程序的 app.js 文件, 在 globalData 里定义一个全局变量 paySuccessUrl: '', 用来保存支付成功跳转 url
1.2 wxmini_webview.js: 小程序中放 web-view 的界面
1.3 wxmini_pay.js: 小程序原生支付界面
1.4 web_pay.vue: 内嵌网页会调起支付的路由组件界面, 由于我是用 vue+vue-router 写的, 所以你最好了解下 vue 和 vue-router, 记得引入微信 jssdk1.3.0, 最新版本才包含小程序相对应方法很遗憾, 微信并没提供 npm 包, github 有人提供的 commonjs 引入方式的微信 jssdk 版本也只有 1.2.0, 所以就只能这样引入了
<script src="./static/jweixin-1.3.0.js"></script>
首先我们像官网那样正常嵌入一个内嵌网页, url 是 wxmini_webview.js 中 data 中定义的变量, webview 加载的就是网页就是这个 url
<web-view src="{{url}}"></web-view>
在内嵌网页 web_pay.vue 里判断当前是否是微信环境
- window.wx.ready(function() {
- isWxMini = window.__wxjs_environment === 'miniprogram'
- })
在内嵌网页 web_pay.vue 调用支付时把支付金额, 支付说明, 支付成功跳转 url...(任何你想要的参数, 记得 encodeURIComponent), 传给小程序原生页面
- if (isWxMini) {
- let jumpUrl = encodeURIComponent(window.location)
- let path = `/page/pay/pay?amount=${amount}&title=${desc}&jumpUrl=${jumpUrl}`
- window.wx.miniProgram.navigateTo({
- url: path
- })
- }
在小程序支付界面 wxmini_pay.js 里获取到内嵌网页传过来的值, 这里演示方便, 实际上是在 page 的 data 里存储这些会显示在界面的值好些
- onLoad: function (options) {
- console.log(options)
- // 获取网页传过来的值
- // TODO 用 es6 解构来获取值 TODO
- jumpUrl = options.jumpUrl
- amount = options.amount
- title = options.title
- ...
- },
支付成功后, 把跳转 url 附带支付结果及当前时间保存到全局变量
- paySuccess () {
- let currentTime = new Date().getTime()
- // 这是为了防止 wxmini_webview.js 文件里调用 setData 时前后两个 url 一致导致路由不触发刷新的 bug, 不理解可继续往下看, 会解释
- jumpUrl = options.jumpUrl+encodeURIComponent(`?payResult=1&time=${currentTime}`)
- //payResult=1 表示支付成功, 这里我偷懒了直接在 url 后面补?, 实际情况应该考虑是否已经有?
- // 为了实现支付成功返回后的无刷新加载, 这里的参数应该是属于路由 web_pay.vue 的, 而不是属于 window.location.search
- getApp().globalData.paySuccessUrl=jumpUrl // 保存跳转 url 到小程序全局变量里
- wx.navigateBack() // 返回会上个页面, 也就是承载网页的容器页面 wxmini_pay.js
- }
回到小程序 wxmini_webview.js, 会触发 onshow, 在里面进行界面无刷新加载
- onShow: function () {
- console.log('on show')
- let paySuccessUrl = getApp().globalData.paySuccessUrl
- getApp().globalData.paySuccessUrl="" // 清空支付成功 url, 防止一些操作触发 onShow 事件
- if (paySuccessUrl) {
- let url = decodeURIComponent(paySuccessUrl)
- this.setData({
- // 这里在次说明下步骤 6 中的 & time=${currentTime}, 就是因为不加这个当你第一次支付成功回来这里
- // 这个 url 跟你第二次支付成功回来这里是一样的, 会导致第二次支付开始, 这里的 setData 方法失效
- url
- })
- }
- },
步骤 7 中的 setData 会触发 webview 中的网页加载, 由于我采用的是 vue-router, 而且前后两个 url 只有路由的参数 query 不一样, 所以并不会触发界面刷新, 也不会触发路由的重新加载, 而是只会触发 beforeRouteUpdate 这个方法, 举个例子, 现在支付前界面是 https://host/#/pay, 然后支付成功后跳转 https://host/#/pay?payResult=1&time=123456, 此时界面不会刷新, pay 路由也不会重新加载, 而是触发 beforeRouteUpdate (to, from, next), 你要做的只是在这里界面解析 to.query 里的数据, 然后该干嘛干嘛
- beforeRouteUpdate(to, from, next) {
- console.log('路由发生改变, 很有可能是小程序的支付成功回调') let payResult = to.query.payResult
- if (payResult) { // 小程序支付成功
- if (payResult === '1') {
- console.log('支付成功, 下班打卡走人')
- }
- }
- next()
- },
这么晚了, 先睡了, 如果有空我再整理个 demo, 如果文章对你有帮助麻烦点个赞
来源: http://www.jianshu.com/p/c9a196d0455e