Hello,我是岚尹~一个热爱技术的项目经理。
不定期更新项目管理、前端以及运维相关方面的经验分享~
如果你对我的文章感兴趣,就请动动你的小手帮赞一下哦。
欢迎关注长期交流~
目录
一、项目背景
最近工作和日常都是千头万绪,而我这言帚忘笤的记性也没法用脑子一一记住,那怎么办呢?
俗话说,好记性不如烂笔头,那就把这些待办项都记下来好了。我找了市面上的待办软件,但都不太符合我的需求。因为我本人一般是提前一周做待办规划,而且每件事只能精确到天,所以我急需一个以周为单位的看板视图,可以规划周一到周末的任务清单,最好是移动端的方式,更方便随时随地进行管理查看。
既然现成的没有,那就自己动手吧。
二、产品设计
1、原型设计
好,说干就干!
先是方案设计,我选了墨刀这个对新手来说门槛比较低的原型工具。上面有很多组件都可以直接使用,上手比较快。界面非常的简单,主要分 Today和Week 两个视图,Today展示当天的待办事项,Week 以看板形式展示当周的待办事项,每一天是一个板块,可切换上一周、下一周的视图。
设计好界面后尝试了几种配色方案,最终采用了第一种比较简单的配色进行开发。
2、功能设计
首先进入小程序后可切换 Today View 和 Week view。在两个视图都可以新增、修改和删除对应日期的待办项,在Week view页面还可切换上一周和下一周的页面。
三、项目结构
我之前有学过一点H5,但没接触过小程序开发,所以在开发中也是一个边学边做的过程。这其中主要参考的学习资料是微信官方的开发文档,有一些细节问题是在CSDN里面搜索其他大佬的文章找到解题思路的。
微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/framework/
开发工具就是使用的微信官方的开发者工具,创建项目的时候需要将申请的小程序APPID与项目进行关联。
项目结构如下截图所示,页面只使用了index一个页面文件,另外引入一个 util.js时间处理模块用于生成当前年度的所有 Week list。
四、项目代码
4.1 wxml 代码:
(1)视图切换:通过按钮 tabx 进行 dayView和weekView的切换,dayView 获取当天的待办项进行展示,weekView获取当周的待办项以看板的形式进行展示。
(2)数据绑定:每一天的待办项以当天的日期为key存储在缓存中,每一次新增、修改、删除都会更新到缓存里面。
如果选择Today页面,代码会去缓存中获取日期为当天的待办项存到 todoList里面,然后通过一层for循环,遍历展示所有当天的待办事项。
如果选择Week页面,代码回去缓存中获取当前星期的所有日期,再通过两层for循环,获取当前周每一天对应的待办事项。
<!--pages/todo/index.wxml-->
<view class="bodyv">
<view class="tabx">
<view class="today" bindtap="viewtoday" id="{{dayView==true?'sview':'nview'}}">Today</view>
<view class="toweek" bindtap="viewweek" id="{{dayView==true?'nview':'wview'}}">Week</view>
</view>
<view wx:if="{{dayView}}" class="dayv">
<view class="dateg" >{{todayTime}}</view>
<scroll-view class="checkv" scroll-y="true" >
<checkbox-group class="checkcl" bindchange="checkHandler" wx:key="tid" wx:for="{{todoList}}" wx:for-item="todo" >
<checkbox data-time="{{todayTime}}" class="checki" bindtap="ckindex" checked="{{todo.tcheck}}" data-index="{{index}}">
</checkbox>
<text class="checki" data-time="{{todayTime}}" bindtap="cedit" data-index="{{index}}">{{todo.twork}}
</text>
</checkbox-group>
</scroll-view>
<image src="../../images/addg.png" class="addg" style="width:80rpx;height:8vh;" mode="aspectFit" bindtap="addHandler" >
</image>
<input id="shuru" value="{{inputValue}}" wx:if="{{showInput}}" placeholder="输入待办事项" focus="true" bindinput="inputHandler" confirm-type="send" bindblur= "cinputcancel" bindconfirm="addbuttonHandler" />
<input id="cedit" value="{{inputValue}}" wx:if="{{showEdit}}" focus="true" bindinput="inputHandler" confirm-type="done" bindconfirm="editHandler" bindblur= "cinputcancel"/>
<view id="cdel" wx:if="{{showEdit}}" bindtap="tapdel" >删除</view>
</view>
<view wx:if="{{dayView==false}}" class="weekv" >
<input id="shuru" value="{{inputValue}}" wx:if="{{showInput}}" placeholder="输入待办事项" focus="true" bindinput="inputHandler" confirm-type="send" bindblur= "cinputcancel" bindconfirm="w_addbuttonHandler" />
<input id="cedit" value="{{inputValue}}" wx:if="{{showEdit}}" focus="true" bindinput="inputHandler" confirm-type="done" bindconfirm="w_editHandler" bindblur= "cinputcancel"/>
<view id="cdel" wx:if="{{showEdit}}" bindtap="w_tapdel" >删除</view>
<image class="w_change" bindtap="lastw" id="w_last" src="../../images/left.png" style="width:50rpx;height:3vh;" mode="aspectFit"></image>
<image class="w_change" bindtap="nextw" id="w_next" src="../../images/right.png" style="width:50rpx;height:3vh;" mode="aspectFit"></image>
<view wx:for="{{Weeklist}}" wx:key="tid" wx:for-item="week">
<view wx:if="{{index==Selectedweek}}">
<view class="w_checkv" data-index="{{index}}" wx:for="{{week}}" wx:key="id" wx:for-index="dayindex" wx:for-item="weekday">
<view class="weektime">{{weekday}}</view>
<checkbox-group class="w_checklist" bindchange="checkHandler" wx:for="{{weektdList[dayindex]}}" wx:key="id" wx:for-item="weektodo" wx:for-index="ckindex">
<checkbox data-time="{{weekday}}" data-day="{{dayindex}}" data-ck="{{ckindex}}" bindtap="w_ckindex" checked="{{weektodo.tcheck}}" ></checkbox>
<text data-time="{{weekday}}" data-day="{{dayindex}}" data-ck="{{ckindex}}" bindtap="w_cedit">{{weektodo.twork}}</text>
</checkbox-group>
<image data-time="{{weekday}}" class="w_add" bindtap="onPullDownRefresh" src="../../images/addg.png" style="width:50rpx;height:4vh;" mode="aspectFit" bindtap="addHandler" >
</image>
</view>
</view>
</view>
</view>
</view>
4.2 js 代码:
(1)util.js 模块:获取当前年度的所有星期输出为一个list,每个星期为一组子list,组内元素为从周一到周天的日期。格式为“yyyy-m-d”。
/*
** 时间戳转换成指定格式日期
** eg.
** dateFormat(11111111111111, 'Y年m月d日 H时i分')
** → "2322年02月06日 03时45分"
*/
const dateFormat = function (timestamp, formats) {
formats = formats || "Y-m-d";
var zero = function (value) {
if (value < 10) {
return "0" + value;
}
return value;
};
var myDate = timestamp ? new Date(timestamp) : new Date();
var year = myDate.getFullYear();
var month = zero(myDate.getMonth() + 1);
var day = zero(myDate.getDate());
var hour = zero(myDate.getHours());
var minite = zero(myDate.getMinutes());
var second = zero(myDate.getSeconds());
return formats.replace(/Y|m|d|H|i|s/gi, function (matches) {
return {
Y: year,
m: month,
d: day,
H: hour,
i: minite,
s: second,
} [matches];
});
};
function formatNumber(n) {
return n.toString().length > 1 ? n : '0' + n
};
/*
获取输入年份的所有星期,每个星期为一个子list
*/
export const getWeek = {
run: (year) => {
let days = getWeek.getDate(year || new Date().getFullYear())
let weeks = {};
for (let i = 0; i < days.length; i++) {
let weeksKeyLen = Object.keys(weeks).length;
let daySplit = days[i].split('_');
if (weeks[weeksKeyLen] === undefined) {
weeks[weeksKeyLen+1 ] = [daySplit[0]]
} else {
if (daySplit[1] == '1') {
weeks[weeksKeyLen+1 ] = [daySplit[0]]
} else {
weeks[weeksKeyLen].push(daySplit[0])
}
}
}
return weeks;
},
getDate: (year) => {
let dates = [];
for (let i = 1; i <= 12; i++) {
for (let j = 1; j <= new Date(year, i, 0).getDate(); j++) {
dates.push(year + '-' + formatNumber(i) + '-' + formatNumber(j) + '_' + new Date([year, i, j].join('-')).getDay())
}
}
return dates;
}
}
module.exports = {
dateFormat,
getWeek,
};
(2)index.js 代码 ,主要说明下新增、编辑和删除的几块核心的功能逻辑。
a,在周View中新增待办事项,通过点击事件e 获取当前触发事件对应的日期,并以此为key,获取到输入框输入的内容为value,存入到缓存中。
addHandler(e){ //点击新增按钮唤起输入框
this.setData({showInput:true});
let dayif=this.data.dayView;
if(dayif==false){
let addtime=e.currentTarget.dataset.time; //对 周view
this.setData({Selectedtime:addtime}); //对 周view
}
},
w_addbuttonHandler(e) { //保存输入内容为待办项, 适用于周视图view
this.setData({showInput:false});
const newItem = this.data.inputValue.trim();
if (!newItem) return;
const newtodo={tcheck:false, twork : newItem};
let dqtime=this.data.Selectedtime;
let td= wx.getStorageSync(dqtime) || [];
td.push(newtodo);
wx.setStorageSync(dqtime, td);
this.getweektd();
},
b, 编辑更新待办项。获取输入框输入的值为value,再更新到对应 list 和存储里面。
w_editHandler(e) // 周view编辑待办事项
{
this.setData({showInput:false});
this.setData({showEdit:false});
const editItem = this.data.inputValue.trim();
let day=this.data.Selectedday;
let ck=this.data.Selectedtd;
let time=this.data.Selectedtime;
let weektd=this.data.weektdList;
weektd[day][ck].twork=editItem;
this.setData({weektdList:weektd});
wx.setStorageSync(time, weektd[day]);
},
c,删除待办项。获取当前所选待办项的index,再从list中删除到对应的元素。
w_tapdel()
{
let day=this.data.Selectedday;
let ck=this.data.Selectedtd;
let time=this.data.Selectedtime;
let weektd=this.data.weektdList;
console.log[weektd];
let week2=weektd[day].splice(ck,1);
wx.setStorageSync(time, weektd[day]);
this.onLoad();
},
五、项目演示
经过一个月的学习和开发自测,最终完成了我的小程序的第一版的研发,小试了一下功能还是比较流畅的,弄了个gif软件录制了下,就是像素比较低。
从一开始学习到完成一款小程序的软件上架还是非常有成就感的,虽然过程中也遇到了很多的问题,但是通过查阅网上的资料结合自己思考都一一解决了,所以一方面非常感谢这些知识分享对自己的帮助,另一方面也更加坚定了我要将自己的学习心得总结输出的决心。
六、小程序入口
现在WeekToDo小程序已经在微信小程序应用市场上架啦,如果对小程序感兴趣的可以扫描以下二维码进入体验,有什么使用建议可以在评论区提给我噢。
大家好,
我是岚尹_nicole,一个热爱文艺的工科生,一个会技术的PM。
主要输出项目管理、前端开发以及运维相关的知识沉淀和总结。
如果你觉得我写的还不错,可以关注下博主哦,博主会努力更新的~
山有木兮木有枝,心悦君兮君不知。