评论

阅读 9小时搞定微信小程序开发 源码总结(小书架)。

入门教程,大神请忽略。整理硬盘发现不知道何时搞来的源码,今天摸鱼看一看有没有值得学习的地方。

目录与页面模块

读代码首先应该认真阅读文档的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
    }
});

中规中矩的小程序,入门还是可以的,代码简洁干净。新手的话撸一遍还是可以的。这样不知道算不算侵权,侵删。

最后一次编辑于  11-15  
点赞 4
收藏
评论

2 个评论

  • 小肥羊🐑🥬
    小肥羊🐑🥬
    11-19

    先赞为上,谢谢分享。

    11-19
    赞同
    回复
  • MonKey. T
    MonKey. T
    11-15

    请教大神 如何用小程序写一个 生产ERP

    11-15
    赞同
    回复 1
    • 小满
      小满
      11-17
      小程序做ERP啊,大工程呀
      11-17
      回复