大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项相关的知识,希望能为你提供帮助。
作者:俞才彬
本文正在参加星光计划3.0–夏日挑战赛
前言初学鸿蒙JS开发技术不久,想要快速结合官方文档上手鸿蒙JS组件开发,本文主要结合HarmonyOS官网上的相关组件及API实现一个根据日期持久化存储待办事项。
效果演示【#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项】
文章图片
实现步骤 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 = https://www.songbingjia.com/android/e.year +"-" + (e.month+1) + "-" + e.day;
this.goDay();
,
onInit()
// 时间选择器默认为当天
this.dateValue = https://www.songbingjia.com/android/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>
currentDategetWeek <
/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="https://www.songbingjia.com/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="https://www.songbingjia.com/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="https://www.songbingjia.com/android/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开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
想了解更多关于开源的内容,请访问:
51CTO 开源基础软件社区
https://ost.51cto.com/#bkwz
推荐阅读
- python中几个常用函数
- python中几个常用小技巧
- SpringBoot 集成缓存性能之王 Caffeine
- Python私有变量与私有方法
- Spring框架系列 - 深入浅出Spring核心之面向切面编程(AOP)
- python随机生成中文字符的方法
- 面试官(MySQL 数据库查询慢,除了索引问题还可能是什么原因())
- fiddler导出jmeter脚本
- 一文入门JavaScript