参考资料:
微信小程序api地址 https://developers.weixin.qq.com/miniprogram/dev/api/open.html#wxgetuserinfoobject
我的github项目地址:https://github.com/Feiyu123/EventAssistant
由于最近小程序比较火, 所以特地研究了一下小程序
一.效果图以及目录:
首页显示日历,
选中日期,点击右下角+号可增加事项,点击右下角铅笔可编辑事项。
新增或者编辑事项,可输入标题和内容以及事项等级,绿色代表一般,黄色代表紧急,红色代表非常紧急。
微信小程序目录结构如下:
每个目录中都有app.js , app.json , app.wxss , project.config.json文件以及pages,utils目录.各个目录的说明如下
二.文件以及目录说明
- 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目录是存放首页以及其他详情页信息的目录
一般每个目录会包含 js, json, wxml 和 wxss等文件
detail.js文件类似于javascript用于处理数据交换和转移,页面初始化和跳转函数
detail.json文件用于控制导航栏的标题,样式,背景颜色等
detail.wxml文件类似于html用于展示页面
detail.wxss文件类似于css文件用于控制页面样式
5.utils目录一般用于放js工具用,可以放js插件或者自制js工具插件
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目录用于存放图片
7.datas目录用于存放数据model和service
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
});
});
}
});