├── pages
├── todos
│ ├── todos.js
│ ├── todos.wxml
│ └── todos.wxss
├── logs
│ ├── logs.json
│ ├── logs.wxss
│ ├── logs.wxml
│ └── logs.js
├── doing
│ ├── doing.wxml
│ ├── doing.wxss
│ └── doing.js
└── todo
│ ├── todo.wxml
│ ├── todo.wxss
│ └── todo.js
├── images
├── wxxcx.gif
├── icon_db.png
├── icon_dbj.png
├── icon_db_HL.png
└── icon_dbj_HL.png
├── app.js
├── app.wxss
├── utils
└── util.js
├── README.md
└── app.json
/pages/todos/todos.js:
--------------------------------------------------------------------------------
1 | Page({
2 |
3 | })
--------------------------------------------------------------------------------
/pages/logs/logs.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志"
3 | }
--------------------------------------------------------------------------------
/images/wxxcx.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maczyt/wxapp_ToDo/HEAD/images/wxxcx.gif
--------------------------------------------------------------------------------
/images/icon_db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maczyt/wxapp_ToDo/HEAD/images/icon_db.png
--------------------------------------------------------------------------------
/images/icon_dbj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maczyt/wxapp_ToDo/HEAD/images/icon_dbj.png
--------------------------------------------------------------------------------
/images/icon_db_HL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maczyt/wxapp_ToDo/HEAD/images/icon_db_HL.png
--------------------------------------------------------------------------------
/images/icon_dbj_HL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maczyt/wxapp_ToDo/HEAD/images/icon_dbj_HL.png
--------------------------------------------------------------------------------
/pages/logs/logs.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
--------------------------------------------------------------------------------
/pages/todos/todos.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 当前没有ToDos, 点击+号创建一个吧
5 |
6 |
--------------------------------------------------------------------------------
/pages/logs/logs.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 | //调用API从本地缓存中获取数据
5 | var logs = wx.getStorageSync('logs') || []
6 | logs.unshift(Date.now())
7 | wx.setStorageSync('logs', logs)
8 | }
9 | })
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 | .container {
3 | height: 100%;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: space-between;
7 | padding: 40rpx 40rpx 0;
8 | box-sizing: border-box;
9 | }
10 |
--------------------------------------------------------------------------------
/pages/todos/todos.wxss:
--------------------------------------------------------------------------------
1 | /**todos.wxss**/
2 | .not-todo {
3 | min-height: 100%;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 | .text {
9 | font-size: 28rpx;
10 | color: #999999;
11 | }
--------------------------------------------------------------------------------
/pages/logs/logs.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | var util = require('../../utils/util.js')
3 | Page({
4 | data: {
5 | logs: []
6 | },
7 | onLoad: function () {
8 | this.setData({
9 | logs: (wx.getStorageSync('logs') || []).map(function (log) {
10 | return util.formatTime(new Date(log))
11 | })
12 | })
13 | }
14 | })
15 |
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | function formatTime(date) {
2 | var year = date.getFullYear()
3 | var month = date.getMonth() + 1
4 | var day = date.getDate()
5 |
6 | var hour = date.getHours()
7 | var minute = date.getMinutes()
8 | var second = date.getSeconds()
9 |
10 |
11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
12 | }
13 |
14 | function formatNumber(n) {
15 | n = n.toString()
16 | return n[1] ? n : '0' + n
17 | }
18 |
19 | module.exports = {
20 | formatTime: formatTime
21 | }
22 |
--------------------------------------------------------------------------------
/pages/doing/doing.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{wisdom}}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{time}}
16 |
17 |
18 | {{tdTitle}}
19 | 进行中
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 微信小程序 ToDoList
2 |
3 | ## 说明书
4 |
5 | 1. 新增ToDo,目前只有[5, 25, 35]的时间选择,以后将可以自定义时间
6 | 2. 在进行todo时,`header`目前是写死了,我写了五条名言随机出现,以后将增加更多或者直接进行网络请求
7 | 3. ToDos(待办集)目前还没开发(因为我也没使用过待办集,嘻嘻~~~)
8 | 4. 导航
9 | ```
10 | 1. todo(首页)
11 | 2. doing(进行页)
12 | 3. todos(待办集页)
13 | 4. logs(日志页)
14 | ```
15 |
16 | ## 开发遇到的问题
17 |
18 | 1. 首先就是页面间的跳转问题,*并不知道该用如何以正确姿势来使用*,看了官方文档只发现到导航,并使用了,结果差强人意
19 | 2. 组件的控制,发现没有DOM(可能是我没找到吧),好多效果都没有实现
20 | 3. 倒计时动画,使用了wx.createAnimation,当然让我很不爽,问题应该出自二
21 | 4. placeholder-(style|class)和按钮的hover-class不起效,估计是姿势不对
22 |
23 | ---
24 |
25 | ## 暂时的效果图
26 |
27 |
28 |
29 | ---
30 |
31 | ## 学习资料
32 |
33 | 1. [官方文档](https://mp.weixin.qq.com/debug/wxadoc/dev/index.html)
34 | 2. [设计指南](https://mp.weixin.qq.com/debug/wxadoc/design/index.html)
35 | 3. [开发工具](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1474644089359)
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/todo/todo",
4 | "pages/todos/todos",
5 | "pages/doing/doing",
6 | "pages/logs/logs"
7 | ],
8 | "window":{
9 | "backgroundTextStyle":"light",
10 | "navigationBarBackgroundColor": "#393F4F",
11 | "navigationBarTitleText": "ToDo",
12 | "navigationBarTextStyle":"white"
13 | },
14 | "tabBar": {
15 | "color": "#515151",
16 | "selectedColor": "#0e932e",
17 | "borderStyle": "black",
18 | "backgroundColor": "#ffffff",
19 | "list": [
20 | {
21 | "pagePath": "pages/todo/todo",
22 | "iconPath": "images/icon_db.png",
23 | "selectedIconPath": "images/icon_db_HL.png",
24 | "text": "待办"
25 | },
26 | {
27 | "pagePath": "pages/todos/todos",
28 | "iconPath": "images/icon_dbj.png",
29 | "selectedIconPath": "images/icon_dbj_HL.png",
30 | "text": "待办集"
31 | }
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/pages/doing/doing.wxss:
--------------------------------------------------------------------------------
1 | /**doing.wxss**/
2 | .container {
3 | background: #ff6666;
4 | }
5 | .wisdom {
6 | width: 100%;
7 | line-height: 1.3;
8 | color: white;
9 | font-size: 30rpx;
10 | font-weight: bold;
11 | }
12 | .wisdom::before {
13 | content: '“';
14 | display: block;
15 | float: left;
16 | font-size: 60rpx;
17 | line-height: .6;
18 | color: white;
19 | margin-right: 20rpx;
20 | }
21 |
22 | /**圆动画**/
23 | .circle {
24 | width: 360rpx;
25 | height: 360rpx;
26 | line-height: 360rpx;
27 | border-radius: 50%;
28 | text-align: center;
29 | margin: -100rpx auto 0;
30 | font-weight: bold;
31 | font-size: 50rpx;
32 | color: white;
33 | position: relative;
34 | }
35 | .left, .right {
36 | position: absolute;
37 | width: 186rpx;
38 | height: 372rpx;
39 | top: -6rpx;
40 | overflow: hidden;
41 | }
42 | .left {
43 | left: -6rpx;
44 | }
45 | .right {
46 | right: -6rpx;
47 | }
48 | #l-after, #r-after {
49 | width: 360rpx;
50 | height: 360rpx;
51 | border-width: 6rpx;
52 | border-style: solid;
53 | border-color: transparent transparent white white;
54 | top: 0;
55 | position: absolute;
56 | border-radius: 50%;
57 | transform: rotate(-135deg);
58 | }
59 | #l-after {
60 | left: 0;
61 | }
62 | #r-after {
63 | right: 0;
64 | border-color: white white transparent transparent;
65 | }
66 |
67 | /**圆动画 END**/
68 |
69 | .td-title {
70 | width: 100%;
71 | margin-bottom: 100rpx;
72 | text-algin: center;
73 | }
74 | .title, .doing {
75 | text-align: center;
76 | font-size: 20rpx;
77 | color: white;
78 | }
79 | .title {
80 | margin-bottom: 10rpx;
81 | font-size: 40rpx;
82 | }
--------------------------------------------------------------------------------
/pages/todo/todo.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 当前没有ToDo, 点击+号创建一个吧
5 |
6 | +
7 |
8 |
9 |
10 |
11 |
12 | {{item.name}}
13 | {{item.time}}分钟
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 暂不提供{{not_active}}功能
37 |
38 |
39 |
40 |
41 | {{item}}
42 |
43 | 取消
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/pages/doing/doing.js:
--------------------------------------------------------------------------------
1 | Page({
2 | data: {
3 | wisdoms: [
4 | '你热爱生命吗?那么别浪费时间,因为时间是构成生命的材料。',
5 | '炫耀什么,说明内心缺少什么。',
6 | '丈夫志四海,万里犹比邻。',
7 | '再牛的梦想,也抵不住你傻瓜似的坚持。',
8 | '知而好问,然后能才。'
9 | ],
10 | wisdom: '',
11 | animateLeft: {},
12 | animateRight: {},
13 | tdTitle: '',
14 | time: '开始',
15 | timeTotal: 0
16 | },
17 | onShow: function() {
18 | var wisdoms = this.data.wisdoms;
19 | var index = Math.floor(Math.random()*wisdoms.length);
20 | var time = Number(wx.getStorageSync('todoTime'));
21 | var name = wx.getStorageSync('todoName');
22 | this.setData({
23 | wisdom: wisdoms[index],
24 | timeTotal: time,
25 | tdTitle: name
26 | })
27 | var animation = wx.createAnimation({
28 | duration: 1000,
29 | timingFunction: "ease",
30 | delay: 0
31 | });
32 | this.animation = animation;
33 | setTimeout(function () {
34 | animation.rotate(45).step();
35 | this.setData({
36 | animateRight: animation.export()
37 | })
38 | }.bind(this), 1000)
39 |
40 | setTimeout(function () {
41 | animation.rotate(45).step();
42 | this.setData({
43 | animateLeft: animation.export()
44 | })
45 | }.bind(this), 2000)
46 |
47 | setTimeout(this.countDown.bind(this), 3000);
48 | },
49 | // 倒计时控制函数
50 | countDown: function() {
51 | var time = this.data.timeTotal
52 | var second = time * 60;
53 | this.changeCD(second);
54 | },
55 | changeCD: function(t) {
56 | setTimeout(function () {
57 | t --;
58 | var branch = 0, second = t % 60;
59 | if (t >= 60) {
60 | branch = Math.floor(t / 60);
61 | }
62 | branch = branch < 10 ? '0'+branch : ''+branch;
63 | second = second < 10 ? '0'+second : ''+second;
64 | this.setData({
65 | time: branch+':'+second
66 | })
67 | var total = this.data.timeTotal * 60;
68 | var animation = this.animation;
69 | if (t > total/2) {
70 | animation.rotate(45-(total - t)/total*360).step()
71 | this.setData({
72 | animateLeft: animation.export()
73 | })
74 | } else {
75 | animation.rotate(-135).step();
76 | this.setData({
77 | animateLeft: animation.export()
78 | })
79 | animation.rotate(45-(total/2 - t)/total*360).step();
80 | this.setData({
81 | animateRight: animation.export()
82 | })
83 | }
84 |
85 | if (t > 0) {
86 | this.changeCD(t);
87 | } else {
88 | this.setData({
89 | time: '结束'
90 | })
91 | }
92 | }.bind(this), 1000);
93 | }
94 | })
--------------------------------------------------------------------------------
/pages/todo/todo.wxss:
--------------------------------------------------------------------------------
1 | /**todo.wxss**/
2 | .not-todo {
3 | min-height: 100%;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 | .text {
9 | font-size: 28rpx;
10 | color: #999999;
11 | }
12 | .add {
13 | position: fixed;
14 | right: 40rpx;
15 | bottom: 40rpx;
16 | background: #393F4F;
17 | color: #ffffff;
18 | font-weight: bold;
19 | font-size: 60rpx;
20 | width: 50rpx;
21 | height: 50rpx;
22 | line-height: 50rpx;
23 | padding: 16rpx;
24 | text-align: center;
25 | border-radius: 50%;
26 | box-shadow: 0 0 8px 1px #666699;
27 | z-index: 1000;
28 | }
29 | .input {
30 | border-bottom: 3rpx solid black;
31 | height: 50rpx;
32 | padding-bottom: 3rpx;
33 | }
34 | .time {
35 | display: flex;
36 | justify-content: center;
37 | align-items: center;
38 | margin-top: 14rpx;
39 | }
40 | .label {
41 | font-size: 34rpx;
42 | color: #393F4F;
43 | margin: 0 36rpx;
44 | }
45 | .radio {
46 | margin-right: 6rpx;
47 | }
48 |
49 | .todo {
50 | border: 2rpx solid #ddd;
51 | height: 110rpx;
52 | box-shadow: 0 1px 1px #666;
53 | margin-bottom: 6rpx;
54 | }
55 | .t-text {
56 | box-sizing: border-box;
57 | padding-left: 45rpx;
58 | color: #ffffff;
59 | width: 80%;
60 | float: left;
61 | position: relative;
62 | }
63 | .cover {
64 | position: absolute;
65 | z-index: 1000;
66 | top: 0; right: 0; bottom: 0; left: 0;
67 | }
68 | .t-title {
69 | font-weight: bold;
70 | height: 40rpx;
71 | font-size: 35rpx;
72 | line-height: 40rpx;
73 | width: 100%;
74 | overflow: hidden;
75 | margin: 20rpx 0 5rpx;
76 | text-overflow: ellipsis;
77 | white-space: nowrap;
78 | }
79 | .t-time {
80 | font-size: 20rpx;
81 | height: 25rpx;
82 | line-height: 25rpx;
83 | }
84 | .t-btn {
85 | line-height: 110rpx;
86 | width: 20%;
87 | float: left;
88 | height: 100%;
89 | }
90 |
91 | .item, .cancel {
92 | font-size: 30rpx;
93 | color: #3399cc;
94 | }
95 | .cancel {
96 | color: #0099cc;
97 | }
98 |
99 | .bg1 {
100 | background: #5C258D;
101 | background: -webkit-linear-gradient(to left, #5C258D , #4389A2);
102 | background: linear-gradient(to left, #5C258D , #4389A2);
103 | }
104 | .bg2 {
105 | background: #085078;
106 | background: -webkit-linear-gradient(to left, #085078 , #85D8CE);
107 | background: linear-gradient(to left, #085078 , #85D8CE);
108 | }
109 | .bg3 {
110 | background: #16222A;
111 | background: -webkit-linear-gradient(to left, #16222A , #3A6073);
112 | background: linear-gradient(to left, #16222A , #3A6073);
113 | }
114 | .bg4 {
115 | background: #EB3349;
116 | background: -webkit-linear-gradient(to left, #EB3349 , #F45C43);
117 | background: linear-gradient(to left, #EB3349 , #F45C43);
118 | }
119 | .bg5 {
120 | background: #1D976C;
121 | background: -webkit-linear-gradient(to left, #1D976C , #93F9B9);
122 | background: linear-gradient(to left, #1D976C , #93F9B9);
123 | }
--------------------------------------------------------------------------------
/pages/todo/todo.js:
--------------------------------------------------------------------------------
1 | //todo.js
2 | Page({
3 | data: {
4 | textShow: true, // 是否有todo存在
5 | modalHidden: true, // 新增todo窗口
6 | flagSubmit: false, // 新增todo时是否填写事件
7 | toastHidden: true, // 消息提示框
8 |
9 | actionTodo: true, // 修改todo
10 | actionSheetItems: ['置顶', '提醒', '编辑', '删除'],
11 | actionWhich: -1,
12 | not_active: '提醒', // 暂不提供提醒功能
13 |
14 | userTime: 25, // 默认时间
15 | addVal: '',
16 |
17 | startD: 0,
18 | naviFlag: false,
19 |
20 | todo: [
21 | /*{
22 | name: '游泳',
23 | time: 20,
24 | bgCls: 'bg1'
25 | },
26 | {
27 | name: '跑步',
28 | time: 20,
29 | bgCls: 'bg3'
30 | },
31 | {
32 | name: '骑车',
33 | time: 20,
34 | bgCls: 'bg5'
35 | }*/
36 | ],
37 | defaults: {
38 | time: [
39 | {value: '5'},
40 | {value: '25', checked: 'true'},
41 | {value: '35'}
42 | ]
43 | }
44 | },
45 | onShow: function () {
46 | if (this.data.todo.length < 1) {
47 | this.setData({
48 | textShow: false
49 | })
50 | }
51 | },
52 | /**
53 | * user defined methods & property
54 | */
55 | // xss & trim
56 | dataFormat: function(data) {
57 | var remove_spaces = /^\s+|\s+$/g,
58 | remove_lt = //g;
60 | return data.toString()
61 | .replace(remove_spaces, '')
62 | .replace(remove_lt, '<')
63 | .replace(remove_gt, '>');
64 | },
65 | // 添加ToDo
66 | addHandle: function(e) {
67 | this.setData({
68 | textShow: true,
69 | modalHidden: false
70 | })
71 | },
72 | // 弹出ToDo内容框
73 | modalChange: function(e) {
74 | if (this.data.flagSubmit) {
75 | this.setData({
76 | modalHidden: true,
77 | todo: [].concat(this.data.todo, {
78 | name: this.data.addVal,
79 | time: this.data.userTime,
80 | bgCls: 'bg'+(Math.ceil(Math.random()*5))
81 | })
82 | })
83 | // 处理新增ToDo
84 | }
85 | },
86 | // input失去焦点触发
87 | inputChange: function(e) {
88 | var val = this.dataFormat(e.detail.value)
89 | if (val.length > 0) {
90 | this.setData({
91 | flagSubmit: true,
92 | addVal: val
93 | })
94 | }
95 | },
96 | // radio修改
97 | rChange: function(e) {
98 | this.setData({
99 | userTime: e.detail.value
100 | })
101 | },
102 |
103 | // 长按todo
104 | changeTodo: function(e) {
105 | var index = e.target.dataset.index;
106 | this.setData({
107 | actionTodo: false,
108 | actionWhich: index
109 | })
110 | },
111 | // 取消长按
112 | cancelTodo: function(e) {
113 | this.setData({
114 | actionTodo: true,
115 | actionWhich: -1
116 | })
117 | },
118 | // 操作todo
119 | todoItem: function(e) {
120 | var index = e.target.dataset.index;
121 | /**
122 | * 开关选项
123 | * 0: 置顶
124 | * 1: 提醒
125 | * 2: 编辑
126 | * 3: 删除
127 | */
128 | switch(index) {
129 | case '0':
130 | // 置顶操作
131 | var todo = this.data.todo;
132 | var item = todo.splice(this.data.actionWhich, 1)[0];
133 | todo.unshift(item);
134 | this.setData({
135 | todo: todo,
136 | actionTodo: true
137 | })
138 | break;
139 | case '1':
140 | this.setData({
141 | not_active: '提醒',
142 | actionTodo: true,
143 | toastHidden: false
144 | })
145 | break;
146 | case '2':
147 | this.setData({
148 | not_active: '编辑',
149 | actionTodo: true,
150 | toastHidden: false
151 | })
152 | break;
153 | case '3':
154 | var todo = this.data.todo;
155 | todo.splice(this.data.actionWhich, 1);
156 | if (todo.length === 0) {
157 | this.setData({
158 | todo: todo,
159 | actionTodo: true,
160 | textShow: false
161 | })
162 | } else {
163 | this.setData({
164 | todo: todo,
165 | actionTodo: true
166 | })
167 | }
168 | break;
169 | }
170 | },
171 | // 消息提示框
172 | toastChange: function(e) {
173 | this.setData({
174 | toastHidden: true
175 | })
176 | },
177 |
178 | // 触摸事件
179 | touchStart: function(e) {
180 | this.setData({
181 | startD: e.touches[0].clientX
182 | })
183 | },
184 | touchMove: function(e){
185 | var to = e.touches[0].clientX;
186 | if ((this.data.startD - to) > 100) {
187 | this.setData({
188 | naviFlag: true
189 | })
190 | }
191 | },
192 | touchEnd: function(e) {
193 | if (this.data.naviFlag) {
194 | this.setData({
195 | naviFlag: false
196 | });
197 | wx.navigateTo({
198 | url: '/pages/todos/todos'
199 | })
200 | }
201 | },
202 |
203 | // 开始todo
204 | startTodo: function(e) {
205 | var index = e.target.dataset.index;
206 | var time = ''+this.data.todo[index].time;
207 | var name = this.data.todo[index].name;
208 | wx.setStorageSync('todoTime', time);
209 | wx.setStorageSync('todoName', name)
210 | wx.navigateTo({
211 | url: '/pages/doing/doing',
212 | complete: function() {
213 | wx.navigateBack();
214 | }
215 | })
216 | }
217 | })
218 |
--------------------------------------------------------------------------------