概述
最近项目使用小程序的web-view把现有项目迁移到小程序里面去。有一些心得,记录下来供以后开发时参考,相信对其他人也有用。
通用
1.企业小程序需要把接口域名填入服务器域名,把web-view的网址域名填入业务域名,把小程序和运营的公众号绑定。
2.授权。
根据授权接口升级公告,无法使用 wx.getUserInfo 接口直接弹出授权框,但是wx.getUserInfo 接口仍旧可以使用。目前微信上的授权和登录一般有2种方式:
- 比较通用,具有独立的个人中心页,每次打开个人中心页都会向开发者服务器发送http请求,请求中有code,开发者服务器利用这个code向微信服务器获取用户数据来确定用户是否已经授权,如果没有授权就需要用户点击授权按钮,如果已经授权就顺便传回用户头像等信息。(这个方法适用于需要传回用户头像等信息的场合)
- 没有独立的个人中心页,也不需要开发者服务器传回用户头像等信息,直接用 wx.getSetting 接口判断用户是否已经授权,没授权则跳转授权页让用户点击授权按钮,已授权则走正常流程,示例代码如下:
wx.getSetting({
success: (settingRes) => {
if (settingRes.authSetting['scope.userInfo']) {
wx.showLoading({ title: 'Loading!' });
wx.getUserInfo({
success: (res) => {
that.globalData.encryptedData = res.encryptedData;
that.globalData.iv = res.iv;
resolve(res);
},
fail: err => reject(err),
})
} else {
// 未授权,跳转授权页
wx.reLaunch({
url: '../auth/index',
});
}
},
fail: err => reject(err),
})
3.接口封装
因为小程序使用的微信api都是回调形式的,并且很容易嵌套,引起回调地狱。所以一般需要使用promise进行封装(如果要使用await的话,需要引入regenerator-runtime库)。使用promise进行封装还能利用catch很简便的处理error信息。示例代码如下:
wxLogin: function () {
const that = this;
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
that.globalData.loginCode = res.code;
resolve(res);
},
fail: err => reject(err),
});
});
},
wxGetSetting: function () {
const that = this;
return new Promise((resolve, reject) => {
wx.getSetting({
success: (settingRes) => {
if (settingRes.authSetting['scope.userInfo']) {
wx.showLoading({ title: 'Loading!' });
wx.getUserInfo({
success: (res) => {
that.globalData.encryptedData = res.encryptedData;
that.globalData.iv = res.iv;
resolve(res);
},
fail: err => reject(err),
})
} else {
// 未授权,跳转授权页
wx.reLaunch({
url: '../auth/index',
});
}
},
fail: err => reject(err),
})
});
},
onLoad(options) {
const that = this;
this.handleUrlFromShare(options);
app.wxLogin()
.then(res => app.wxGetSetting())
.then(res => that.requestCodeApi())
.catch((err) => {
wx.hideLoading();
this.setData({
isFirstLogin: true,
});
// 正常登陆
if (err.hideToast) return;
// 登陆失败
that.showErrorToast(err, 'Login Again Please!');
console.log('Login failed-------', err);
});
},
web-view组件的使用
小程序的web-view是承载网页的容器,相当于iframe。它会自动铺满整个小程序页面,个人类型与海外类型的小程序暂不支持使用,并且 navigationStyle: custom 对
1.web-view 里面的项目可以通过判断 userAgent 中包含 miniProgram 字样来判断小程序 web-view 环境(微信7.0.0以上)。示例代码如下:
export function isMiniProgram() {
return !!navigator.userAgent.match(/miniProgram/i);
}
2.不能在web-view里面打开新窗口,所以在项目上需要判断小程序环境,在需要新窗口打开的时候变成本窗口打开。
3.分享
在有 web-view 的小程序页面可以利用 options.webViewUrl 拿到 web-view 里面的网址,然后在分享的时候带上这个网址,在跳转页面判断是否有url参数来接收这个网址。
需要注意的是,
- 如果网址中有token等信息,需要先去掉这个信息。
- 如果网址中有汉字等符号,就需要使用encodeURIComponent转义一下。
- 有些时候,可能需要双重转义才能拿到想要的url。
示例如下:
deleteTkAndRtk: function(url) {
const host = url.slice(0, url.indexOf('?'));
let queryArr = url.slice(url.indexOf('?') + 1, url.length).split('&');
queryArr = queryArr.filter(
query => query.indexOf('tk=') === -1 && query.indexOf('rtk=') === -1);
if (queryArr.length !== 0) {
return host + '?' + queryArr.join('');
}
return host;
},
onShareAppMessage: function (options) {
const url = options.webViewUrl;
const filteredUrl = this.deleteTkAndRtk(url);
return {
path: `pages/index/index?url=${encodeURIComponent(filteredUrl)}`,
title: 'YiDrone',
}
},
onLoad: function (options) {
if (options.url) {
this.setData({
// 这里的encodeURI必不可少。。。
yidroneUrl: encodeURI(decodeURIComponent(options.url)),
})
}
},
4.jssdk
web-view中的项目可以给小程序发送信息,还可以控制小程序的页面跳转,方法如下:
// 首先在项目内引入 weixin-js-sdk 库
npm install weixin-js-sdk --save
// 然后在plugin文件夹建立 wx-sdk.js
import Vue from 'vue';
import wx from 'weixin-js-sdk';
Vue.prototype.$wx = wx;
// 然后在main.js里面判断小程序环境按需引入 wx-sdk.js
// weixin-js-sdk
try {
if (isMiniProgram()) {
import('./plugins/wx-sdk').then(() => {});
}
} catch (err) {
console.error('>>>wx-sdk', err);
}
// 最后在需要的地方进行操作
if (isMiniProgram() && this.$wx) {
// 不能使用这个格式:this.$wx.miniProgram.postMessage({ data: 'bar' });
this.$wx.miniProgram.postMessage({ data: { foo: 'bar' } });
this.$wx.miniProgram.navigateTo({ url: '../auth/index' });
}
// 在小程序的web-view组件加入 handleBindmessage 事件
<web-view src="{{ url }}" bindmessage="handleBindmessage"></web-view>