#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项

大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项相关的知识,希望能为你提供帮助。
作者:俞才彬
本文正在参加星光计划3.0–夏日挑战赛
前言初学鸿蒙JS开发技术不久,想要快速结合官方文档上手鸿蒙JS组件开发,本文主要结合HarmonyOS官网上的相关组件及API实现一个根据日期持久化存储待办事项。
效果演示【#夏日挑战赛# HarmonyOS - 实现带日期效果的待办事项】

#夏日挑战赛# 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

    推荐阅读