1.小程序登录逻辑的实现。
小程序登录的实现,官方建议自己保存用户登录状态,不要频繁调用 wx.login,否则会限制登录。
这里说一下我自己实现登录的逻辑,无代码,实现逻辑看下图:
2.小程序返回首页的实现。
这里说个返回首页的场景,比如首页可以点击 button 进入详情页(wx.navigateTo),详情页此时再回首页,可以直接 wx.navigateBack 即可。
如果详情页面允许分享,用户就可能直接通过分享出去的小程序卡片进入详情页,此时,回首页的逻辑就与上面说的不同了,必须再重新打开首页。详细请看下方代码。
页面互相跳转的逻辑,尽量设计简单一些,否则的话,很坑人。比如,A 页可以跳至 B 页面,B 页面又可以跳至 C 页面,B 和 C 页面都允许分享,此时,从 C 页面返回 B 页面的逻辑就比上面的要复杂。
3.防止用户多次点击。
比如用户提交表单数据,点击 submit 按钮,需要调用保存数据的 API,如果不做误点击处理,用户可能会多次点击 submit,这样就会保存冗余数据。
可以提取公用方法到 util.js 中,如下:
WXML:
JavaScript:
500毫秒以内的点击都只会处理一次,时间长短自己可以调整。
4.小程序之间如何传值。
(1)URL 传值
这种方式最常用,比如:
wx.navigateTo({
url: '../detail/detail?id='+id+'&access_token='+access_token
})
这里面直接通过跳转页面的 URL 进行传值,然后在另一个页面进行接收:
onLoad: function (opt) {
console.log('cid =' + opt.cid);
console.log('access_token =' + opt.access_token);
}
这种传值方式只适合值比较少的时候使用,传值比较多的时候,还是建议写本地缓存。
(2)本地缓存
小程序 API 提供了本地缓存数据的 API,默认可以缓存10M的数据,如下:
wx.setStorageSync('testData', testData);
testData 可以是一个 object,在需要的页面直接调用 wx.getStorageSync 即可获取,这样就解决了传值较少的问题了。
(3)全局 App
其实还有第三种方式,就是全局 App 变量。app.js 和 app.wxss 中的代码都是全局生效的,所以我们可以利用这一点儿,在不同页面之间进行传值。
App({
onLaunch: function () {
},
globalData: {
host: 'https://xxx.com',
}
})
也可以在其他 JavaScript 里面动态修改 globalData,如 getApp().globalData.host = 'XXX';
。
5.获取小程序表单数据。
做过小程序的同学,都知道小程序中是通过数据渲染页面的,没办法获取 Dom 节点,表单提交就不能像 H5 页面那样去获取表单项的见容了。
小程序中的表单提交必须用户手动触发,不能通过 JavaScript 自动提交。
获取表单数据有两种方式。
(1)获取 event 中的值。
正常的 form 表单提交,都可以在 event.detail.value 中获取到页面表单项填写的值,如下:
这里需要在 WXML 中的,把 input、textarea、radio 等表单项设置 name 属性,上图中的 title,就是 input 的 name 属性。
<input type="text" name="title" auto-focus='true' />
这种方式获取表单数据很方便,但是,如果需要对表单数据有清除功能,我们该如何实现呢?如下图所示。
我们先来看看第二种方式。
(2)通过设置变量值保存表单数据。
这种方式也比较好实现,就是给表单项绑定事件,当内容发生变化时,set 一下变量值。所以,提交表单的时候直接获取变量值就 OK 了。
<input type="text" bindinput="inputTitle" name="title" value="{{title}}" auto-focus='true' />
可以给 input 绑定事件 (bindinput="inputTitle"),然后在 inputTitle 里面简单处理一下:
inputTitle: function (e) {
this.setData({
title: e.detail.value,
titleEmpty: e.detail.value.length == 0
})
},
上面的 titleEmpty 是为了判断 title 是否为空,如果为空,就不显示右侧的“清除 icon”。这种方式很容易实现上面说的清空内容。
在 form 的 submit 时,直接 var title = this.data.title;
就获取到了表单数据,很方便。
6.如何获取更多的 formId
相信使用过小程序的同学,多少都收到过小程序的通过消息,如下:
这类通知消息,是和好友消息一样展示在微信的聊天列表中,所以,点击率还是比较高的。想实现这种小程序的模板消息,就必须要获取用户的 formid 才可以(如何发消息,请仔细查阅小程序官方文档)。
我们来说一下如何获取 formId:
- 必须通过 form 组件提交才能获取到 formId;
- 给 form 组件设置 report-submit="true" 属性;
- 给 form 组件添加 bindsubmit 事件绑定,携带 form 中的数据触发 submit 事件,event.detail = {value : {'name': 'value'} , formId: ''}; 4.必须用户手动触发提交表单,不能 JavaScript 模拟提交,所以,页面上必须要有提交按钮。
看一下示例代码:
<form report-submit='true' bindsubmit='userSubmit'>
<button class='button' bindtap='copy' form-type='submit'>复制</button>
</form>
以上示例就可以在 userSubmit 里获取到 formId 了:
userSubmit: function (e) {
console.log(e.detail.formId);
},
需要注意一点,开发工具里面是没办法查看到真实的 formId 的,会是这样一句提示:“the formId is a mock one”,提交给服务端就可以拿到了。
7.小程序页面跳转后的刷新逻辑
场景是这样,用户从列表 A 页面跳至 B 页面,并在 B 页面做了更新操作(编辑或删除信息),当用户再 back 到 A 页面时,需要对 A 页面的数据进行刷新;如果用户未做更新操作,back 回 A 页面后,就不需要对 A 页面数据刷新。
我们可以在 B 页面操作时,写入一个数据在本地,如下代码:
formSubmit: function(){
// 操作之后,本地缓存一个值
util.setStorage('needRefresh', true);
},
返回 A 页面时,再到 page 的 onShow 方法中去判断一下就 OK。
onShow: function(){
var needRefresh = util.getStorage('needRefresh');
if(needRefresh){
// 这里写入你的刷新逻辑
......
util.removeStorage('needRefresh');
}
},
8.小程序如何判断转发到群还是好友
这个问题,要区分一下分享之前和分享之后就好办了。
当小程序分享之前,小程序无法区分到底是分享给了好友,还是分享给了微信群。也就是说,你想在分享之前去做些事情,这是不可以的,做不到。
分享之后,有间接的办法来知道小程序卡片分享的是好友还是群,先看一下截图:(重要通知小程序)
我们今天主要来说说,分享后是如何核对好友卡片和群卡片的。实现思路:通过场景值来判断。
上图是小程序官方给的场景值,已经对单人聊天会话和群聊天会话做了区分。
我们可以在 app.js 里面的 onLaunch 方法或者 onShow 方法获取到场景值:
拿到值之后,你可以保存全局变量,或者写入本地缓存,在相应的 page.js 里面去做判断,如果是群聊,显示群聊界面,如果是私聊,显示私聊界面。
上面只说了如何区分群聊还是私聊,那么仅限某个群可见这功能又如何实现呢?
思路是:分享小程序卡片之后,获取到群 id,当群用户点击群内小程序卡片时,也会获取一个群 id,这两个群 id 相同,则表明是同一个群;没有获取到群 id,表明不是从群聊中打开小程序卡片;两个群 id 不同,则表明不是同一个群。
上面已经说了,有两种场景可以获取群 id。
第一,小程序卡片分享到群聊中。分享完成之后,有个分享成功的回调方法,可以在此方法中获取到 shareTickets:
拿到 shareTickets 之后,可以调用 wx.getShareInfo,获取解密 gid 会用到的向量和加密值,传给服务端进行解密(小程序中所有的解密操作,都放在服务端进行)。
注:上面成功回调时,res.shareTickets 是个 list,因为分享给好友和群的时候,可以多选,最多选9项。
第二,从群聊中打开小程序卡片时。从群中打开小程序卡片,会在 app.js 里面的 onLaunch 方法和 onShow 方法中获取到 shareTickets。
拿到 shareTickets 之后,去服务端解密。
相信大家也有看到过,有些小程序做了群排行榜功能。实现方式,也是同样的道理。
9. 小程序之间互相跳转的注意点儿
小程序之间互相跳转,使用 wx.navigateToMiniProgram 来实现,从这里访问官方文档。
上面有一句话,要注意:打开同一公众号下关联的另一个小程序。如果没有关联同一个公众号,则无法成功打开另一小程序。
(1)公众号关联小程序。
公众号关联小程序后,将可在图文消息、自定义菜单、模板消息等功能中使用小程序。
关联规则如下:
所有公众号都可以关联小程序。
一个公众号可关联10个同主体的小程序,3个不同主体的小程序。
一个小程序可关联3个公众号。
公众号一个月可新增关联小程序13次,小程序一个月可新增关联5次。
关联流程如下:
登录公众号后台 -> 小程序 -> 小程序管理 -> 添加 -> 关联小程序。
如果你已经关联成功,那就可以看一下代码的实现了,如下:
if (wx.navigateToMiniProgram) {
wx.navigateToMiniProgram({
appId: recommend.appid,
path: '/pages/detail/detail?cid=' + cid
})
} else {
wx.previewImage({
urls: [recommend.qrcode],
})
}
wx.navigateToMiniProgram,从基础库 1.3.0 开始支持,低版本需做兼容处理。低版本时,我们就直接给用户显示一张带二维码的图片,告知用户需要升级微信版本,或者扫描二维码才能进入。
测试的时候,需要跳到另一个小程序的体验版,可以设置 envVersion 参数:develop(开发版),trial(体验版),release(正式版)。
[图片上传中...(image-e39dd-1521534564186-0)]
如果你公司的小程序产品比较多,又想把数据打通,这种方式是个不错的选择~
10.公用方法建议写在 util.js 中
开发小程序过程中,大家都可能有自己的提取公用代码逻辑,我建议大家把公用方法放在 util.js 中。
app.js 中主要获取 options 参数时用,比如识别小程序码,需要获取 scene 参数;从群聊中打开小程序卡片,你可以获取 shareTickets 参数;小程序之间互相跳转,你可以获取到 appid 等参数。
部分 util.js 方法如下:
function postFormId(formId) {
wx.request({
url: getApp().globalData.host + '/v1/formid',
data: { 'formid': formId, 'access_token': getToken() },
method: 'POST'
})
}
function toIndex() {
var pageCount = getCurrentPages().length;
if (pageCount > 1) {
wx.navigateBack({
delta: 1
})
} else {
wx.redirectTo({
url: '../index/index'
})
}
}
function buttonClicked(self) {
self.setData({
buttonClicked: true
})
setTimeout(function () {
self.setData({
buttonClicked: false
})
}, 500)
}
function getStorage(key){
try{
wx.getStorageSync(key);
}
catch(e) {
getStorage(key);
}
}