小程序webview组件使用的坎坷历程(地图交互为重点)
应项目需求,需要将H5内嵌在小程序壳子里。通过小程序授权登录的方式进入H5商城(vue项目)。那么需要用到的就是微信小程序的webview组件啦~~说实话,看官网文档介绍的赶脚不是特别复杂,但实操过程中遇到各种小坑,有的时候开发者工具内可以实现的功能,真机上无法运行。心累累滴~~本地改版的内容收益最大的是收货地址模块(小程序与H5地图交互功能)以及分享功能,所以,想分享下自己开发中遇到的问...
应项目需求,需要将H5内嵌在小程序壳子里。通过小程序授权登录的方式进入H5商城(vue项目)。
那么需要用到的就是微信小程序的webview组件啦~~说实话,看官网文档介绍的赶脚不是特别复杂,但实操过程中遇到各种小坑,有的时候开发者工具内可以实现的功能,真机上无法运行。
心累累滴~~本地改版的内容收益最大的是收货地址模块(小程序与H5地图交互功能)以及分享功能,所以,想分享下自己开发中遇到的问题希望对大家有帮助哦~~~
- 判断当前运行环境,不允许之前的H5商城在微信浏览器端打开,借鉴官网提供的方法:https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html
在运用的时候,一开始用的是getEnv方法,但没有效果,不知道是什么原因。查了资料,和网友很分享的写法一样,后来没折腾了。换了第一种方法在WeixinJsBridgeReady回调,当浏览器打开是会提示当前不是小程序环境,在小程序中打开ok。
注意: 使用时要引入jssdk1.3.2~~~,项目中在main.js中引入的,当然如果你也是vue项目的话,可以npm install weixin-js-sdk,安装成功后在package.json文件中可以看到,再main.js中引入即可,两种方法都可以,该项目中选择的是后者。
下面上代码:
2.小程序授权登录,将H5商城之前的微信登录授权改成从小程序入口登录授权。该功能不用多说,做过小程序的盆友都烂熟于心啦。既然是从小程序登录,逻辑就在小程序页面内实现,所以先把商城项目之前调微信登录的逻辑给干掉咯,哈哈哈~~
下面上代码:
首先是调取用户信息授权窗口,目前小程序只能用button触发,这个大家都知道的。。。
触发按钮后调起授权登录窗口,获取当前用户信息(昵称,头像,城市,省份,iv。。。),当用户点击授权确定按钮时,
则触发login方法
因接口需要,登录时把当前的userToken进行缓存。当然,每次登录都需要清除缓存哦~
进入首页使用webview组件实现,大家注意:跳转的网页地址需要加密,在商城首页接受时需要解密,这是webview的一个坑点!!!
3.webview实现分享功能,官网提供的方法了解下:
https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html
介绍的很简洁,大致思路就是这样的。运用到项目中如下图所示:
4.webView与H5网页实现地图交互,敲黑板,,,,,,,
下面详细说下发生的一系列故事吧。一开始用的是腾讯地图组件,实现点击详细地址后,显示地图可以搜索定位选择某个地址带回到文本框内。方法很简单,之前在腾讯位置服务平台使用到的地图组件申请一个key,再结合提供的demo例子,几分钟解决。
下面上代码:
实现的页面风格就是以下这种:
没毛病,腾讯地图组件代码简洁,用的也很方便。。但是!在webview组件里使用地图组件(不管是腾讯,百度还是高德)都会受到一个限制阻碍。小程序后台管理需要添加业务域名,刚刚使用的腾讯组件域名为apis.map.qq.com,无法添加到开发小程序的业务域名中,查资料看社区,发现这个bug官方回复暂不支持。此路不通,需要找其他的方法去实现地图选址功能。
下面说说如何在webview中实现H5与小程序地图api的交互吧
1.H5页面中需要在触发选择地址按钮的时候跳转到小程序指定的map页面,唤起小程序地图
2.小程序内创建map文件,通过调用getLoction,chooseLocation调起地图组件并选择相关地址
<!--pages/map/map.wxml-->
<view>
<web-view src="{{web_src}}"></web-view>
</view>
Page({
/**
* 页面的初始数据
*/
data: {
mapUrl: '',
mapDataStr: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 解析当前H5网页的url
// 页面跳转过来时把收获地址的信息传递过来,以免H5跳转到小程序内选择完地址后,再次刷新页面,导致你填写的联系人,电话号码等信息被清空。
mapUrl为收获地址的url(https://xxx.xxx.com/Addrress)
mapDataStr打印出来为带过来的参数信息?addressId=10&name=hhhhhh&mobile=13023212132)
var returnUrlArr = decodeURIComponent(options.returnUrl).split('?');
this.setData({
mapUrl: returnUrlArr[0],
mapDataStr: returnUrlArr[1]
})
},
onReady:function(e){
this.mapCtx = wx.createMapContext('myMap');
this.getCenterLocation();
},
getCenterLocation(){
let that = this;
wx.getLocation({
type: 'wgs84', //返回可以用于wx.openLocation的经纬度
success: function(res) {
// 如果打开地图没有选择地址则跳转到原H5页面,否则选择地址后再进行跳转
let latitude = res.latitude
let longitude = res.longitude
wx.chooseLocation({
latitude: latitude,
longitude: longitude,
scale: 28,
success: function (res) {
var getUserInfos = wx.getStorageSync('userInfo')
var userToken = wx.getStorageSync('userToken')
var returnDataStr = that.data.mapDataStr + '&avatarUrl=' + encodeURIComponent(getUserInfos.avatarUrl) + '&nickName=' + getUserInfos.nickName + '&address=' +res.address + '&addNameInfo=' + res.name + '&userToken=' + userToken + '&longitude=' + res.longitude + '&latitude=' + res.latitude ;
var returnUrl = encodeURI(that.data.mapUrl +"?"+ returnDataStr);
that.setData({
// 携带选择地址res.address返回到H5页面中
web_src: returnUrl
})
},
fail: function(res) {
wx.navigateBack({
delta: 1
})
}
})
},
})
},
})
3.主要的逻辑在小程序中实现滴。大概思路就是这样的了。webview传参基本都是在跳转的url后紧跟着。如果像我这样传参较多的情况下,写成一个对象从url上来回传值,当然。需要把变成字符串对象传值哦。并且参数需要进行加密(encodeURIComponent),在接受页面的地方进行解密(decodeURIComponent)即可。webview的src需要加密一下哦。如上图代码所示(encodeURI),在H5页面中接受需要解密:
// 选择地址后返回页面保存地址信息,用户信息,userToken
getQueryMapString() {
var _this = this;
let searchStr = decodeURI(window.location.search);
searchStr = searchStr.substring(1, searchStr.length);
let searchArr = searchStr.split("&"); // 分割成字符串数组
let searchData = {};
searchArr.forEach(ele => {
let eleArr = ele.split("=");
// 此处是对当前的url中参数进行解密操作
if (
eleArr[1].indexOf("%E6") >= 0 ||
eleArr.indexOf("%E5") >= 0 ||
eleArr.indexOf("9B") > 0
) {
searchData[eleArr[0]] = decodeURIComponent(eleArr[1]);
} else {
searchData[eleArr[0]] = eleArr[1];
}
// 小程序页面带过来的信息
_this.newAddress.address = searchData.addNameInfo;
_this.lat = searchData.latitude;
_this.lng = searchData.longitude;
_this.userToken = searchData.userToken;
// 缓存UserToken
if (_this.userToken) {
axios.defaults.headers.common["User-Token"] = _this.userToken;
}
});
},
在开发工具中因勾选了不校验合法域名那栏,导致真机上存在的问题,在开发者工具中无法复现。
所以在开发过程中,一定要多用手机测试。当然,webview的坑必须线上测才有真实体验。发现bug,体验版本不一定能测出来。
正如,在小程序中点击导航栏回退按钮,如果你尝试一下,地图点击取消的时候,会出现空白页,再次回退才能跳到进入小程序之前的H5新增收货地址页面。所以,在倒数第三张图中,加了一个fail方法:没有选择任何地址只是唤起地图的场景,点击小程序导航栏回退按钮,则回调到上级操作页面。很方便哦~~
目前上线版本也很实用,没有出现什么bug。只是觉得webview跳转到H5链接会有些许的延迟卡顿。不过正常浏览速度还是可以的,希望以上整理内容对大家有点帮助呢。后期将开发网页商城与小程序的支付交互功能,到时再更新~
更多推荐
所有评论(0)