开发前
首次接触微信小程序,第一步就是去微信官方文档看了小程序的介绍及设计指南,梳理一下小程序的申请开发流程以及一些注意事项,避免后期开发过程中不必要的麻烦。申请小程序账号还是比较快的。
需要了解的是小程序的appid是识别小程序身份的唯一标识,申请之后不可变更。小程序的名字一个月可申请修改五次。
申请下来之后就是开发前的项目构建以及版本管理工具的选择,考虑到小程序本身可选用支持npm构建并且有组件化的支持可以满足基本需求,因此在项目紧急的情况下小程序没有选用任何框架,而是选用小程序基础的框架及组件进行开发。之后可以了解一下相对好评的wepy框架。起初我们选用的是微信小程序代码管理集成git进行的版本管理,个人感觉还是比较好用的,就是不同的编辑器对代码缩进不同,git也认为这是差异让我有些无奈。后来因为公司有统一的tfs管理代码,因此也抛弃了git回归了tfs。
开发中
对于项目的配置及目录结构,官方文档已经说的很明确了,所以此处就不再赘述了。此处附上官方文档链接
项目的配置里在关于导航配置这一项有说明开发者可以自定义导航,但是总结前人的经验来看,在大多数机型上,自定义导航会出现上拉下滑页面的同时导航跟着移动的情况(当然,不介意的可以忽略此信息)
查看了很多小程序以及根据小程序自身的规范,不建议强制用户授权登录之后才能查看体验小程序,基于此建议产品经理们不要在首页设计和用户相关的展示。我是踩着坑过来的,如下图所示:用户登录之后在回来首页应该展示用户自己的信息,我的做法是每次进入onShow的时候判断用户是否登录来展示对应的内容,但是这就造成了每次进入首页都要重新渲染的弊端。因为onShow是每次都会执行的,但是onLoad并不是每次都会执行。
项目中我们都会遇到很多模块有很多相似之处,此时我们就要考虑是否将其做成可复用的公共组件,比如暂无内容和loading等。那么在小程序里面,我们可以选用component进行组件开发,组件说明链接
在我的项目中,我将提示类的和loading类的,专题树,文献类的等分别放在一个组件中,这样就保证了同样的功能模块可以复用而不用每次都做重复的工作。在设计公共组件的时候,我们需要考虑组件的可拓展性,以便能够更好的适应之后的需求变更(哪位朋友在组件设计有研究的可以思维碰撞一下)
对请求的统一处理,小程序提供了wx.request方法发起请求,但是我们在遇到请求异常时通常只需要写一次就可以了,这时候我们就要考虑对请求进行统一的封装处理。首先对所有的公共异常进行特异化处理,再有考虑是否可以结合promise方便使用then方法,因为小程序支持构建npm模块,因此我们可以使用npm安装promise来处理请求。此处我是这样处理的,欢迎各位提意见。
const Tips = require("./tips.js");
const tips = new Tips.default();
class commonApi{
constructor(){
};
theWayByGet(url, data, token, requestSource){
return this.getData(url, data, token, requestSource, "GET");
};
theWayByPost(url, data, token, requestSource) {
return this.getData(url, data, token, requestSource, "POST");
};
theWayByPut(url, data, token, requestSource) {
return this.getData(url, data, token, requestSource, "PUT");
};
getData(url, data, token, requestSource, method){
let source, opt = {dataType: 'json' };
opt.header = (requestSource === "sso" || requestSource === "isms") ? {"accesstoken": token} : {"token": token};
if(url.indexOf("https") >= 0){
url = url;
source = "outer";
}else{
if(requestSource === 'sso'){
url = `${此处忽略域名}/api/api/${url}`;
}else if(requestSource === 'isms'){
url = `${此处忽略域名}/ismsApi/api/${url}`;
}else{
url = `${此处忽略域名}/psmcapi/api/v1.0/${url}?device=wx`;
}
}
return new Promise((resolve, rejects) => {
wx.request({
url,
data,
method,
...opt,
success: (res) => {
if (res.statusCode == 200) {
if(requestSource === "sso" || requestSource === "isms" || source === "outer"){
resolve(res);
} else {
if(res.data.errorCode === 0){
resolve(res);
} else if (res.data.errorCode === -2) {
tips.showToast("登录相关异常", "none");
} else if (res.data.errorCode === 1) {
tips.showToast("参数错误相关信息", "none");
} else if (res.data.errorCode === -1) {
tips.showToast("未知异常", "none");
}
}
}else{
tips.showToast("请求失败", "none");
}
},
fail: (res) => {
//检查网络状态
wx.getNetworkType({
success (res) {
const networkType = res.networkType;
// console.log(networkType);
if(networkType === "none"){
//无网环境
wx.navigateTo({
url: '/pages/noNetwork/noNetwork',
});
}else {
//弱网环境
}
}
});
rejects(res);
},
});
});
};
}
export default commonApi
项目涉及的分享扫码等功能在文档都有,按照步骤下来没什么问题,此处就不具体说明了。
项目优化
首先说下小程序的渲染机制,小程序可以运行在三端,即微信开发者工具,Android,iOS。需要注意的是,小程序在这三端的渲染并不相同,
可以看出小程序的渲染层和逻辑层是分开的,那么他们之间是怎么通信的呢?当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现,也就是setData的工作原理。官方不建议频繁的去操作setData,说明参考如下链接链接描述
因此我们在实际项目中就要考虑如何优化setData,最常见的就是滚动加载,我们可以在每页加载的时候只对该页进行setData赋值操作,这点微信小程序是支持的。