#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项
Posted 开源基础软件社区官方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项相关的知识,希望对你有一定的参考价值。
作者:俞才彬
前言
初学鸿蒙JS开发技术不久,想要快速结合官方文档上手鸿蒙JS组件开发,本文主要结合HarmonyOS官网上的相关组件及API实现一个根据日期持久化存储待办事项。
效果演示
实现步骤
1. 确定两个页面
首先确定有两个页面:选择日期页面、待办事项页面。选择日期页面将选择的日期如:2022-6-16
作为路由参数传递到代办事项页,后者把这个日期作为缓存的key
去取数据,并渲染在页面上。
2. 选择日期页面
页面结构如下:
<!-- index.hml -->
<div class="container">
<text class="welcome">
<span>创建你的待办事项</span>
</text>
<div class="date-picker">
<text class="pick-date" @click="showDatePicker">
<span>点我选择日期</span>
</text>
<!-- 不写value,视图将不会显示 -->
<picker
id="picker"
type="date"
start="2002-2-5"
end="2030-6-5"
selected=" getCurrentDate "
onchange="dateOnChange"
show="false">
</picker>
</div>
</div>
样式如下:
/* index.less */
@theme_color: rgba(120, 132, 206, .8);
.container
background-color: @theme_color;
flex-direction: column;
align-items: center;
justify-content: center;
.welcome
color: #fff;
margin-bottom: 120px;
font-size: 24px;
font-weight: 600;
border-bottom: 2px solid #fff;
.date-picker
justify-content: center;
.pick-date
color: #FFF;
line-height: 43px;
border: 2px solid #fff;
border-radius: 50px;
padding: 10px 50px;
font-size: 20px;
时间选择器使用picker
组件,type
设置为date
,默认值为今天。选择日期时,触发onchange
事件,拿到选择的日期,点击确定后,跳转至待办事项页面,并将日期作为路由参数传递。
// index.js
import router from @system.router;
export default
data:
dateValue: , // 时间选择器的值
,
// 去待办事项页面
goDay()
const self = this;
router.push(
uri: "pages/day/day",
params:
currentDate: self.dateValue,
);
,
showDatePicker()
this.$element("picker").show();
,
dateOnChange(e)
this.dateValue = e.year + "-" + (e.month+1) + "-" + e.day;
this.goDay();
,
onInit()
// 时间选择器默认为当天
this.dateValue = this.getCurrentDate;
,
computed:
// 获取当前日期
getCurrentDate()
let now = new Date();
return now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
3. 待办事项页面
3.1 进入待办事项页面
进入待办事项页面需要根据路由参数(传递的日期)判断是否是今天,是今天则展示动态的数字时钟。
还需要根据路由参数从缓存中读取待办事项数据,并设置给list
,用于页面展示。调用官网API的storage.get()
方法,由于后续修改数据可能涉及多层回调,考虑到代码可读性,将从缓存中读数据操作用Promise
封装。
// day.js
data:
keyword: "", // 输入框内容
list: [],
// list: [
// title: 学习鸿蒙OS, done: false ,
// title: 学习js开发鸿蒙应用, done: true ,
// title: 学习java开发鸿蒙应用, done: false ,
// title: 学习鸿蒙OS, done: false ,
// ],
currentDate: , // 上个页面传来的选择日期
clock: , // 今天的时钟
timerID: null,
istoday: false, // 是否今天
noTodoTips:
todayTxt: 请先添加今天的待办事项吧!,
notTodayTxt: 当日还没有待办事项!
,
isListEmpty: false,
isDoneEmpty: false,
isUnDoneEmpty: false
,
onInit()
// 判断是否是今天
this.istoday = (new Date(this.currentDate).toDateString() === new Date().toDateString());
if (this.istoday) // 如果是今天则显示时钟
this.timerID = setInterval(this.updateTime, 1000);
this.updateTime();
this.setList();
,
// 从缓存中拿数据并赋值给list
async setList()
let res = await this.getListFromStorage(this.currentDate);
this.list = res;
// 用于控制总、未完成、完成的视图显示
this.isListEmpty = (this.list.length == 0);
this.isUnDoneEmpty = (this.list.filter(item => !item.done).length == 0);
this.isDoneEmpty = (this.list.filter(item => item.done).length == 0);
,
getListFromStorage(key)
return new Promise((resolve, reject) =>
storage.get(
key: key,
success: function(data)
resolve(JSON.parse(data));
,
fail: function(data, code)
reject(JSON.parse(data));
,
complete: function() ,
default: [] // key不存在则返回的默认值
);
);
,
updateTime()
let now = new Date();
this.clock =
this.zeroPadding(now.getHours(), 2)
+ : +
this.zeroPadding(now.getMinutes(), 2)
+ : +
this.zeroPadding(now.getSeconds(), 2);
,
zeroPadding(num, digit)
let zero = ;
for (let i = 0; i < digit; i++)
zero += 0;
return (zero + num).slice(-digit);
,
3.2 分别展示全部、未完成、已完成待办事项
使用tabs
组件和列表组件list
渲染分别展示全部、未完成和已完成待办事项。
若无数据,全部区域展示 “请先添加今天的待办事项吧!”,已完成和未完成区域展示无数据图片。
<!-- day.hml -->
<div class="container">
<div class="time-area">
<text class="select-date">
<span> currentDate getWeek </span>
</text>
<text class="today-time">
<span if=" istoday "> clock </span>
</text>
</div>
<tabs class="tabs" onchange="tabChange">
<tab-bar class="tabBar">
<text class="tabBarItem all">全部( getListSum )</text>
<text class="tabBarItem undo">未完成( getUndoSum )</text>
<text class="tabBarItem done">已完成( getDoneSum )</text>
</tab-bar>
<tab-content class="tabContent">
<div>
<div if=" isListEmpty " class="no-data-all">
<text>
<span> (getListSum == 0) && istoday ? noTodoTips.todayTxt : noTodoTips.notTodayTxt</span>
</text>
</div>
<list class="todo-list" else>
<list-item class="todo-item" for=" list ">
<div class="todo-item-inner">
<input type="checkbox" onchange="changeStatus($idx)" checked=" $item.done "></input>
<piece content=" $item.title " closable="true" onclose="remove($idx)" class="piece-item"></piece>
</div>
</list-item>
</list>
</div>
<div>
<div if=" isUnDoneEmpty " class="no-data-img">
<image class="no-data-images img-way" src="../../common/images/no_data.jpg" style="width: 200px;"></image>
</div>
<list class="todo-list" else>
<list-item class="todo-item" for=" list ">
<div class="todo-item-inner" if=" !$item.done ">
<input type="checkbox" onchange="changeStatus($idx)" checked=" $item.done "></input>
<piece content=" $item.title " closable="true" onclose="remove($idx)" class="piece-item"></piece>
</div>
</list-item>
</list>
</div>
<div>
<div if=" isDoneEmpty " class="no-data-img">
<image class="no-data-images img-way" src="../../common/images/no_data.jpg" style="width: 200px;"></image>
</div>
<list class="todo-list" else>
<list-item class="todo-item" for=" list ">
<div class="todo-item-inner" if=" $item.done ">
<input type="checkbox" onchange="changeStatus($idx)" checked=" $item.done "></input>
<piece content=" $item.title " closable="true" onclose="remove($idx)" class="piece-item"></piece>
</div>
</list-item>
</list>
</div>
</tab-content>
</tabs>
<div class="header">
<input
id="addinp"
class="input"
type="text"
value=" keyword "
maxlength="20"
enterkeytype="done"
placeholder="请输入待办事项"
onchange="change">
</input>
<button class="buttons" @click="add">添加</button>
</div>
</div>
在计算属性中计算全部、未完成、已完成的个数,用于tabs
展示。
// day.js
computed:
// 全部个数
getListSum()
return
Object.prototype.toString.call(this.list) == [object Array] ? this.list.length : 0;
,
// 返回未完成项目的个数
getUndoSum()
return this.list.filter(item => !item.done).length;
,
// 返回完成项目的个数
getDoneSum()
return this.list.filter(item => item.done).length;
,
// 星期几
getWeek()
let week = [天, 一, 二, 三, 四, 五, 六];
let day = (new Date(this.currentDate)).getDay();
return 星期 + week[day];
,
3.3 添加待办事项
在输入框中输入内容,点击添加按钮,添加待办事项,并调用storage.set()
API将list
存在缓存中,成功之后更新list
以更新视图。若输入框无内容,使用prompt.showToast
提示输入内容。
// day.js
change(e)
this.keyword = e.value;
,
add()
if (this.keyword === "") return prompt.showToast(
message: "请输入内容"
)
this.list.push( title: this.keyword, done: false );
this.keyword = "";
this.setStorage();
,
// 封装函数供修改或者添加缓存中的数据
setStorage()
const self = this;
storage.set(
key: this.currentDate,
value: JSON.stringify(this.list),
success: function()
self.setList();
,
fail: function(data, code)
);
,
3.4 完成 / 取消待办事项
点击选择框,勾选或者取消勾选待办事项,并设置缓存。
// day.js
changeStatus(index)
this.list[index].done = !this.list[index].done;
this.setStorage();
,
3.5 删除待办事项
使用piece
组件的onclose
事件删除待办事项,删除前使用prompt.showDialog
弹窗方法询问是否删除,点击确认后删除,并设置缓存。
// day.js
showDialog(options = )
if (JSON.stringify(options) == "") return;
prompt.showDialog(options);
,
remove(index)
let self = this;
let options =
message: "确定要删除吗?",
buttons: [
text: 确定,
color: #87cbff,
,
text: 取消,
color: #666666,
,
],
success: function(data)
if(data.index == 0)
self.list.splice(index, 1);
self.setStorage();
,
cancel: function()
console.log(dialog cancel callback);
,
;
this.showDialog(options);
,
总结
以上就是完成带日期缓存效果的待办事项的全部过程了,算是对鸿蒙JS开发快速上手的初步认识吧, 后期还可以对其完善,比如在样式、功能方面等等,希望可以和大家共同学习鸿蒙更多的知识,一起进步。
更多原创内容请关注:中软国际 HarmonyOS 技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
以上是关于#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项的主要内容,如果未能解决你的问题,请参考以下文章