微信小程序--事项助手

参考资料:
微信小程序api地址 https://developers.weixin.qq.com/miniprogram/dev/api/open.html#wxgetuserinfoobject

我的github项目地址:https://github.com/Feiyu123/EventAssistant

由于最近小程序比较火, 所以特地研究了一下小程序

一.效果图以及目录:

首页显示日历,
选中日期,点击右下角+号可增加事项,点击右下角铅笔可编辑事项。


微信小程序效果图1.png

新增或者编辑事项,可输入标题和内容以及事项等级,绿色代表一般,黄色代表紧急,红色代表非常紧急。


微信小程序效果图2.png

微信小程序目录结构如下:


微信小程序目录结构.png

每个目录中都有app.js , app.json , app.wxss , project.config.json文件以及pages,utils目录.各个目录的说明如下

二.文件以及目录说明

  1. app.js是小程序的脚本代码。我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。调用框架提供的丰富的 API,如本例的同步存储及同步读取本地数据。
import { log, promiseHandle } from 'utils/util';

App({
    getUserInfo(cb) {
        if (typeof cb !== "function") return;
        let that = this;
        if (that.globalData.userInfo) {
            cb(that.globalData.userInfo);
        } else {
            promiseHandle(wx.login).then(() => promiseHandle(wx.getUserInfo)).then(res => {
                that.globalData.userInfo = res.userInfo;
                cb(that.globalData.userInfo);
            }).catch(err => {
                log(err);
            });
        }
    },

    globalData: {
        userInfo: null
    },

    //自定义配置
    settings: {
        debug: true, //是否调试模式
        moreLink: 'http://github.com/oopsguy'
    }
});  

​ 2.app.json 是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口背景色,配置导航条样式,配置默认标题。注意该文件不可添加任何注释。

{
  "pages":[
    "pages/index/index",  //首页目录
    "pages/detail/detail"  // 详情页目录
  ],
  "window":{
    "backgroundTextStyle":"light", //背景文字样式
    "navigationBarBackgroundColor": "#E14848", //导航栏背景颜色
    "navigationBarTitleText": "事项助手", // 导航栏文字标题
    "navigationBarTextStyle":"white" // 导航栏文字样式
  }
}

3.app.wxss 是整个小程序的公共样式表。我们可以在页面组件的 class 属性上直接使用 app.wxss 中声明的样式规则。

page {
  font-family: 'microsoft yahei ui';
  font-size: 28rpx;
  background-color: #1D1D26;
  color: #FFF;
}

/*float action*/
.float-container {
  position: fixed;
  bottom: 40rpx;
  right: 40rpx;
  overflow: hidden;
}
.float-action {
  width: 100rpx;
  height: 100rpx;
  border-radius: 50%;
  box-shadow: 2px 2px 10px rgba(0, 0, 0, .5);
  background: #E14848;
  z-index: 100;
  text-align: center;
  opacity: .5;
  margin-left: 40rpx;
  float: right;
}
.float-action:active {
  opacity: 1
}
.float-action image {
    width: 60rpx;
    height: 60rpx;
    margin-top: 20rpx;
}

.bg-normal {
  background: #46BC62 !important;
}
.bg-warning {
  background: #ECAA5B !important;
}
.bg-danger {
  background: #E14848 !important;
}

.color-primary {
  color: #46BC62 !important;
}
.color-warning {
  color: #ECAA5B !important;
}
.color-danger {
  color: #E14848 !important;
}

.border-normal {
  border: 2rpx solid #46BC62 !important;
}
.border-warning {
  border: 2rpx solid #ECAA5B !important;
}
.border-danger {
  border: 2rpx solid #E14848 !important;
}

.text-center {
  text-align: center !important;
}

4.pages目录是存放首页以及其他详情页信息的目录


存放首页及详情页目录.png

一般每个目录会包含 js, json, wxml 和 wxss等文件
detail.js文件类似于javascript用于处理数据交换和转移,页面初始化和跳转函数
detail.json文件用于控制导航栏的标题,样式,背景颜色等
detail.wxml文件类似于html用于展示页面
detail.wxss文件类似于css文件用于控制页面样式

5.utils目录一般用于放js工具用,可以放js插件或者自制js工具插件


js工具插件.png

bluebird.js是js开源插件,Promise异步代码实现控制流
uitl.js导入开源插件的Promise实现自封装函数

import Promise from 'bluebird';

function formatTime(date) {
    let year = date.getFullYear()
    let month = date.getMonth() + 1
    let day = date.getDate()

    let hour = date.getHours()
    let minute = date.getMinutes()
    let second = date.getSeconds()

    return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

function formatNumber(n) {
    n = n.toString()
    return n[1] ? n : '0' + n
}

function getDateStr(date) {
    if (!date) return '';
    return date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日';
}

/**
 * 生成GUID序列号
 * @returns {string} GUID
 */
function guid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

/**
 * 记录日志
 * @param {Mixed} 记录的信息
 * @returns {Void}
 */
function log(msg) {
    if (!msg) return;
    if (getApp().settings['debug'])
        console.log(msg);
    let logs = wx.getStorageSync('logs') || [];
    logs.unshift(msg)
    wx.setStorageSync('logs', logs)
}

/**
 * @param {Function} func 接口
 * @param {Object} options 接口参数
 * @returns {Promise} Promise对象
*/
function promiseHandle(func, options) {
    options = options || {};
    return new Promise((resolve, reject) => {
        if (typeof func !== 'function')
            reject();
        options.success = resolve;
        options.fail = reject;
        func(options);
    });
}

module.exports = {
    formatTime: formatTime,
    guid: guid,
    log: log,
    promiseHandle: promiseHandle,
    getDateStr: getDateStr,
    formatNumber: formatNumber
}


6.images目录用于存放图片


images存放图片.png

7.datas目录用于存放数据model和service


datas目录用于存放数据.png

Config.js是数据模型

module.exports = {
    ITEMS_SAVE_KEY: 'todo_item_save_Key',
    LEVEL: {
        normal: 1,
        warning: 2,
        danger: 3
    }
};

DataRepository.js是数据仓库,类似于dao层,实现增删改查

import Config from 'Config';
import { guid, log, promiseHandle } from '../utils/util';

class DataRepository {

    /**
     * 添加数据
     * @param {Object} 添加的数据
     * @returns {Promise} 
     */
    static addData(data) {
        if (!data) return false;
        data['_id'] = guid();
        return DataRepository.findAllData().then(allData => {
            allData = allData || [];
            allData.unshift(data);
            wx.setStorage({ key: Config.ITEMS_SAVE_KEY, data: allData });
        });
    }

    /**
     * 删除数据
     * @param {string} id 数据项idid
     * @returns {Promise}
     */
    static removeData(id) {
        return DataRepository.findAllData().then(data => {
            if (!data) return;
            for (let idx = 0, len = data.length; idx < len; idx++) {
                if (data[idx] && data[idx]['_id'] == id) {
                    data.splice(idx, 1);
                    break;
                }
            }
            wx.setStorage({ key: Config.ITEMS_SAVE_KEY, data: data });
        });
    }

    /**
     * 批量删除数据
     * @param {Array} range id集合
     * @returns {Promise}
     */
    static removeRange(range) {
        if (!range) return;
        return DataRepository.findAllData().then(data => {
            if (!data) return;
            let indexs = [];
            for (let rIdx = 0, rLen = range.length; rIdx < rLen; rIdx++) {
                for (let idx = 0, len = data.length; idx < len; idx++) {
                    if (data[idx] && data[idx]['_id'] == range[rIdx]) {
                        indexs.push(idx);
                        break;
                    }
                }
            }

            let tmpIdx = 0;
            indexs.forEach(item => {
                data.splice(item - tmpIdx, 1);
                tmpIdx++;
            });
            wx.setStorage({ key: Config.ITEMS_SAVE_KEY, data: data });
        });

    }

    /**
     * 更新数据
     * @param {Object} data 数据
     * @returns {Promise} 
     */
    static saveData(data) {
        if (!data || !data['_id']) return false;
        return DataRepository.findAllData().then(allData => {
            if (!allData) return false;
            for (let idx = 0, len = allData.length; i < len; idx++) {
                if (allData[idx] && allData[idx]['_id'] == data['_id']) {
                    allData[idx] = data;
                    break;
                }
            }
            wx.setStorage({ key: Config.ITEMS_SAVE_KEY, data: data });
        });

    }

    /**
     * 获取所有数据
     * @returns {Promise} Promise实例
     */
    static findAllData() {
        return promiseHandle(wx.getStorage, { key: Config.ITEMS_SAVE_KEY }).then(res => res.data ? res.data : []).catch(ex => {
            log(ex);
        });
    }

    /**
     * 查找数据
     * @param {Function} 回调
     * @returns {Promise} Promise实例
     */
    static findBy(predicate) {
        return DataRepository.findAllData().then(data => {
            if (data) {
                data = data.filter(item => predicate(item));
            }
            return data;
        });
    }
}

module.exports = DataRepository;

DataService.js类似于service业务逻辑层,实现具体的逻辑业务

import DataRepository from 'DataRepository';
import { promiseHandle } from '../utils/util';

/**
 * 数据业务类
 */
class DataSerivce {

    constructor(props) {
        props = props || {};
        this.id = props['_id'] || 0;
        this.content = props['content'] || '';
        this.date = props['date'] || '';
        this.month = props['month'] || '';
        this.year = props['year'] || '';
        this.level = props['level'] || '';
        this.title = props['title'] || '';
    }

    /**
     * 保存当前对象数据
     */
    save() {
        if (this._checkProps()) {
            return DataRepository.addData({
                title: this.title,
                content: this.content,
                year: this.year,
                month: this.month,
                date: this.date,
                level: this.level,
                addDate: new Date().getTime()
            });
        }
    }

    /**
     * 获取所有事项数据
     */
    static findAll() {
        return DataRepository.findAllData()
            .then(data => data.data ? data.data : []);
    }

    /**
     * 通过id获取事项
     */
    static findById(id) {
        return DataRepository.findBy(item => item['_id'] == id)
            .then(items => (items && items.length > 0) ? items[0] : null);
    }

    /**
     * 根据id删除事项数据
     */
    delete() {
        return DataRepository.removeData(this.id);
    }

    /**
     * 批量删除数据
     * @param {Array} ids 事项Id集合
     */
    static deleteRange(ids) {
        return DataRepository.removeRange(ids);
    }

    /**
     * 根据日期查找所有符合条件的事项记录
     * @param {Date} date 日期对象
     * @returns {Array} 事项集合
     */
    static findByDate(date) {
        if (!date) return [];
        return DataRepository.findBy(item => {
            return item && item['date'] == date.getDate() &&
                item['month'] == date.getMonth() &&
                item['year'] == date.getFullYear();
        }).then(data => data);
    }

    _checkProps() {
        return this.title && this.level && this.date && this.year && this.month;
    }
}

module.exports = DataSerivce;

而pages/index目录下的detail.js类似于view层,处理和页面交换数据

import DataService from '../../datas/DataService';
import { getDateStr } from '../../utils/util';
import { LEVEL } from '../../datas/Config';

Page({
    data: {
        item: '',
        levelSelectData: [LEVEL.normal, LEVEL.warning, LEVEL.danger],
    },

    onLoad(option) {
        const { id } = option;
        let item = DataService.findById(id).then((item) => {
            item['addDate'] = getDateStr(new Date(item['addDate']));
            console.log(item)
            this.setData({
                item: item
            });
        });
    }
});

你可能感兴趣的:(微信小程序--事项助手)