目录与页面模块
读代码首先应该认真阅读文档的
README.md
。 看下小书架页面模块、目录结构清晰,虽然模块不多,实际业务开发中首先应该构思拆解业务模块,确定目录结构。小程序包大小超过 2M 需要分包,所以从一开始确定目录结构的时候就要考虑进去,不然线上跑起来再去分包会有点小麻烦。
目录结构
├── config
│ └── config.js
├── images
├── pages
│ ├── books
│ │ ├── books.js
│ │ ├── books.json
│ │ ├── books.wxml
│ │ └── books.wxss
│ ├── comment
│ │ ├── comment.js
│ │ ├── comment.js
│ │ ├── comment.js
│ │ └── comment.wxss
│ ├── detail
│ │ ├── detail.js
│ │ ├── detail.js
│ │ ├── detail.js
│ │ └── detail.wxss
│ ├── my
│ │ ├── my.js
│ │ ├── my.js
│ │ ├── my.js
│ │ └── my.wxss
│ └── myBooks
│ ├── myBooks.js
│ ├── myBooks.js
│ ├── myBooks.js
│ └── myBooks.wxss
├── utils
│ └── util.js
├── app.js
├── app.json
├── app.wxss
└── project.config.json
各页面模块
页面 | 描述 |
---|---|
books | 首页/书籍列表页 |
comment | 评论页面 |
detail | 书籍详情页 |
my | 个人中心页 |
myBooks | 已购书籍页 |
接口封装
小书架没有对 wx.request 封装。考虑到是入门教程,没做处理也是正常。接口请求路径封装在 config.js
// 服务器域名
const baseUrl = 'http://127.0.0.1:[your port]/';
// 获取书籍信息接口地址(可选择全部或单个书籍)
const getBooksUrl = baseUrl + 'api/book/getBooks';
//...
module.exports = {
getBooksUrl: getBooksUrl
//...
};
也可以根据个人习惯进行封装,这里一定要写注释以及考虑后期维护
let returnCancel = (memberId, refundId) => http.post(`api/return/goods/cancel`, { memberId: memberId, refundId: refundId})
export default {
returnCancel
};
页面
book
book.js
代码干净、整洁。注释很详细,虽然这是入门教程,但我们开发的时候也要养成这样的好习惯。
data
data: {
bookList: [], // 书籍列表数组
indicatorDots: false, // 是否显示轮播指示点
autoplay: false, // 是否自动播放轮播
sideMargin: '100rpx', // 幻灯片前后边距
showLoading: true // 是否显示loading态
//...
},
onLoad
getBookList 方法获取所有书籍列表,不要把所有的 wx.request 都写在load里面,简单封装下可维护性大大提高
/**
* 获取所有书籍列表
*/
getBookList: function() {
let that = this;
wx.request({
url: api.getBooksUrl,
data: {
is_all: 1
},
success: function(res) {
let data = res.data;
// console.log(data);
if (data.result === 0) {
setTimeout(function() {
that.setData({
bookList: data.data,
showLoading: false
});
}, 800);
}
},
error: function(err) {
console.log(err);
}
});
},
onLoad: function(options) {
let that = this;
that.getBookList();
},
loading处理
<block wx:if="{{showLoading}}">
<view class="donut-container">
<view class="donut"></view>
</view>
</block>
// 默认 true 。getBookList 方法成功回调里设为 false。没有错误处,接口请求失败的话应该也做下处理的
comment
comment.js
封装了检查用户输入的方法,实际业务中如果输入较多的话,可以提炼到 unit.js。封装了 wx.showToast
// 检查输入是否为空,起名称注意语义话
checkEmpty: function(input) {
return input === '';
},
/**
* 检查用户是否输入了非法字符
*/
checkIllegal: function(input) {
let patern = /[`#^<>:"?{}\/;'[\]]/im;
let _result = patern.test(input);
return _result;
},
/**
* 检查用户输入
*/
checkUserInput: function() {
/*
* 检测用户输入
* 1. 是否包含非法字符
* 2. 是否为空
* 3. 是否超出长度限制
*/
let that = this;
let comment = that.data.comment;
let showToastFlag = false;
let toastWording = '';
if (that.checkEmpty(comment)) {
showToastFlag = true;
toastWording = '输入不能为空';
} else if (that.checkIllegal(comment)) {
showToastFlag = true;
toastWording = '含有非法字符';
} else if (comment.length > 140) {
showToastFlag = true;
toastWording = '长度超出限制';
}
if (showToastFlag) {
that.showInfo(toastWording);
return false;
} else {
return true;
}
},
封装toast
showInfo: function(info, icon = 'none', callback = () => {}) {
wx.showToast({
title: info,
icon: icon,
duration: 1500,
mask: true,
success: callback
});
},
detail
简单的返回刷新处理以及下载进度条
// 从上级页面返回时 重新拉去评论列表
backRefreshPage: function() {
let that = this;
that.setData({
commentLoading: true
});
that.getPageData();
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
if (wx.getStorageSync('isFromBack')) {
wx.removeStorageSync('isFromBack')
this.backRefreshPage();
}
}
进度条(这个还是很少见的需求,很可爱)
<!-- 下载进度条 -->
<view class="loading-container" wx:if="{{downloading}}">
<progress
percent="{{downloadPercent}}"
stroke-width="6"
activeColor="#1aad19"
backgroundColor="#cdcdcd"
show-info
/>
</view>
my
主要是检查登陆。myBooks没有什么亮眼的操作,就不上场了。
data: {
userInfo: {}, // 用户信息
hasLogin: wx.getStorageSync('loginFlag')
? true
: false // 是否登录,根据后台返回的skey判断
},
app.js
主要负责检查处理登陆信息
App({
// 小程序启动生命周期
onLaunch: function () {
let that = this;
// 检查登录状态
that.checkLoginStatus();
},
// 检查本地 storage 中是否有登录态标识
checkLoginStatus: function () {
let that = this;
let loginFlag = wx.getStorageSync('loginFlag');
if (loginFlag) {
// 检查 session_key 是否过期
wx.checkSession({
// session_key 有效(为过期)
success: function () {
// 直接从Storage中获取用户信息
let userStorageInfo = wx.getStorageSync('userInfo');
if (userStorageInfo) {
that.globalData.userInfo = JSON.parse(userStorageInfo);
} else {
that.showInfo('缓存信息缺失');
console.error('登录成功后将用户信息存在Storage的userStorageInfo字段中,该字段丢失');
}
},
// session_key 过期
fail: function () {
// session_key过期
that.doLogin();
}
});
} else {
// 无登录态
that.doLogin();
}
},
// 登录动作
doLogin: function (callback = () => {}) {
let that = this;
wx.login({
success: function (loginRes) {
if (loginRes.code) {
/*
* @desc: 获取用户信息 期望数据如下
*
* @param: userInfo [Object]
* @param: rawData [String]
* @param: signature [String]
* @param: encryptedData [String]
* @param: iv [String]
**/
wx.getUserInfo({
withCredentials: true, // 非必填, 默认为true
success: function (infoRes) {
console.log(infoRes,'>>>')
// 请求服务端的登录接口
wx.request({
url: api.loginUrl,
data: {
code: loginRes.code, // 临时登录凭证
rawData: infoRes.rawData, // 用户非敏感信息
signature: infoRes.signature, // 签名
encryptedData: infoRes.encryptedData, // 用户敏感信息
iv: infoRes.iv // 解密算法的向量
},
success: function (res) {
console.log('login success');
res = res.data;
if (res.result == 0) {
that.globalData.userInfo = res.userInfo;
wx.setStorageSync('userInfo', JSON.stringify(res.userInfo));
wx.setStorageSync('loginFlag', res.skey);
callback();
} else {
that.showInfo(res.errmsg);
}
},
fail: function (error) {
// 调用服务端登录接口失败
that.showInfo('调用接口失败');
console.log(error);
}
});
},
fail: function (error) {
// 获取 userInfo 失败,去检查是否未开启权限
wx.hideLoading();
that.checkUserInfoPermission();
}
});
} else {
// 获取 code 失败
that.showInfo('登录失败');
console.log('调用wx.login获取code失败');
}
},
fail: function (error) {
// 调用 wx.login 接口失败
that.showInfo('接口调用失败');
console.log(error);
}
});
},
// 检查用户信息授权设置
checkUserInfoPermission: function (callback = () => { }) {
wx.getSetting({
success: function (res) {
if (!res.authSetting['scope.userInfo']) {
wx.openSetting({
success: function (authSetting) {
console.log(authSetting)
}
});
}
},
fail: function (error) {
console.log(error);
}
});
},
// 获取用户登录标示 供全局调用
getLoginFlag: function () {
return wx.getStorageSync('loginFlag');
},
// app全局数据
globalData: {
userInfo: null
}
});
中规中矩的小程序,入门还是可以的,代码简洁干净。新手的话撸一遍还是可以的。这样不知道算不算侵权,侵删。