我和微信开发的恩怨情仇
接触微信开发以来,感叹于小程序的发展之迅速,以为对着小程序的api文档就能一把梭,然而还是各种踩坑,一把鼻涕一把眼泪的赶着需求,成功交付,线上正常使用,想想还是记录一下这段时间经历的遇到的问题,给各位微信开发小白一点点不成熟的小建议~
逐渐变态.png本篇主要针对小程序开发和网页微信鉴权。
小程序
由于之前一直以react开发为主,这是初次接触小程序,而小程序的写法跟vue的写法很像,是比较容易上手愉快撸起来的框架。因此我总结了下遇到的小程序相关的一些常见问题,具体的语法使用请自行查询api文档:https://developers.weixin.qq.com/miniprogram/dev/framework/
1、登录问题
微信官方登录图解.png图中出现的几个名词:
code —— 临时登录凭证, 有效期五分钟, 通过 wx.login() 获取。
appid —— 用户在该小程序下的用户唯一标识, 永远不变, 服务端通过 code 获取。
wx.getUserInfo
调用前需要用户授权,获取用户信息。
getUserInfo方法需要通过调用小程序的button组件,设置open-type为getUserInfo,可以通过方法获取用户的基本信息和其他登录需要的凭证信息。
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">授权登录</button>
getUserInfo(){
wx.getUserInfo({
success: function(res) {
console.log('res返回的是:userInfo,rawData,signature,encryptedData,iv',res)
}
})
}
wx.login
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)等。
wx.login({
success (res) {
if (res.code) {
console.log('获取的登录凭证code',res.code)
} else {
console.log('登录失败!' + res.errMsg)
}
}
当前面两个方法调用返回数据凑齐,就可以将这些信息组装好,调用后端接口,后端接收到数据之后,调用微信的登录凭证校验接口,获得用户唯一标识openId和 会话密钥session_key。
2、上拉刷新+下拉刷新
简单说下小程序自带的上拉和下拉刷新的用法。
下拉刷新:小程序每个页面都有一个.json的配置文件,设置enablePullDownRefresh为true,可以使用小程序的下拉刷新组件。
{
enablePullDownRefresh:true
}
在页面逻辑中可以通过onPullDownRefresh方法拿到下拉刷新的回调事件。
onPullDownRefresh(){
//可以在这个方法写更新数据的请求
}
上拉刷新:
可以在json中设置距离页面底部多少触发方法
{
onReachBottomDistance:50//上拉到距离底部50的距离,就开始触发回调方法
}
在页面中可以通过回调方法来写处理的逻辑。
onReachBottom(){
//处理加载更多的逻辑
}
然而,实际使用的场景中,还会遇到更复杂的情况...
小猪佩奇式脸瘫.png
例如:实现一种滑动模块中实现页面滚动的效果,这就涉及到swiper和scroll-view的嵌套使用。
<view>
<view>xxxx</view><!--例如搜索框或者是tab之类的展示区域-->
<swiper
style="height:{{allHeight - otherHeight}}px"><!--需要给swiper一个固定高度,总高度-swiper的其他高度-->
<swiper-item>
<scroll-view
scroll-y
@scrolltoupper="upload"
@scrolltolower="loadMore"
>
<!--具体节点展示内容-->
</scroll-view>
</swiper-item>
</swiper>
</view>
如果用scroll-view来处理页面滚动问题,enablePullDownRefresh方法会失效,当下拉时,下拉刷新事件没有被触发,这两种下拉方式是不能一并存在的。
3、微信请求方法封装
微信的http请求,封装后再抛出调用。
const request=(url,options)=>{
const apiUrl='xxxxx'
return new Promise((resolve,reject)=>{
wx.request({
url:`${apiUrl}${url}`,
method:options.method,
header:{
token:wx.getStorageSync('token'),
}
...options,
success:({statusCode,data,errMsg}=>{
resolve({
success:true,
result:data,
status:statusCode
})
}),
fail:()=>{
resolve({
success:false,
result:{}
})
},
})
})
}
4、路由跳转
方法 | 解释 |
---|---|
wx.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
wx.reLaunch | 关闭所有页面,打开到应用内的某个页面 |
wx.redirectTo | 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。 |
wx.navigateTo | 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面 |
wx.navigateBack | 关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages获取当前的页面栈,决定需要返回几层。 |
H5网页微信鉴权问题
业务场景中需要将某个页面分享到微信朋友,这里涉及到的关于OAuth鉴权。
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
也就是允许给用户一个令牌,用来访问他们存放在特定的网站。每个令牌授权一个特定的网站,这样OAuth允许用户授权第三方网站的时候可以不需要用户填入账号和密码。
如果我们经常有使用微信的小程序或者在某个微信分享出来的链接中操作,就知道,当第一次点开某个链接的时候,微信会弹出用户的授权窗口(这里需要注意,分两种授权情况,静默授权是不会询问用户是否同意授权给微信公众账号的,底下会提到),如果授权成功,这个时候获取appId和appsecret两个参数,
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=1#wechat_redirect
最后祭出微信分享的方法
/**
* wx分享方法
* @class WeChatService
*/
export default function WeChatService(wxInfo,shareInfo,successCb,failCb){
const wx = window['wx'];
wx.config({
debug: false,
appId: wxInfo.appId, // 和获取Ticke的必须一样------必填,公众号的唯一标识
timestamp: wxInfo.timestamp, // 必填,生成签名的时间戳
nonceStr: wxInfo.nonceStr, // 必填,生成签名的随机串
signature: wxInfo.signature,// 必填,签名,见附录1
//需要分享的列表项:发送给朋友,分享到朋友圈,分享到QQ,分享到QQ空间
jsApiList: [
'onMenuShareAppMessage', 'onMenuShareTimeline',
]
})
let link = window.location.href
if(window.location.href.indexOf('from') != -1 || window.location.href.indexOf('isappinstalled') != -1){
// 二次分享url重定向 - 需要截取一次分享后微信自动拼接的url参数&from=singlemessage&isappinstalled=0
link = window.location.href.split('&from=singlemessage')[0]; // 这里的split中的字符串会变换(?或&),主要看自己的url
}
//link = link.replace(/share/,'shareRedirect')
let share_config = {
imgUrl: shareInfo.imgUrl,
desc: window.location.href,
title: shareInfo.title,
link: link,
success: function (res) {
//分享成功后的回调函数
successCb()
}
};
wx.ready(function () {
wx.onMenuShareAppMessage(share_config);//分享给好∞友
wx.onMenuShareTimeline(share_config);//分享到朋友圈
});
wx.error(function (){
failCb('失败了')
})
}