一、功能概述
如果说周视图帮助用户了解短期变化趋势,那么月视图则更适合观察长期习惯。本篇文章围绕“月视图统计”页面,介绍如何在Cordova Web 层以日为单位聚合整个月的喝水数据,并通过OpenHarmony ArkTS提供原生侧的月度概览展示,为后续实现更精细的趋势分析打下基础。文章仍然采用一段代码一段说明的节奏,并附带 ArkTS 示例代码。
二、Web 端月视图页面结构
<divid="month-view-page"class="page page-month-view"><h1>本月喝水统计</h1><tableclass="data-table"id="table-month-view"><thead><tr><th>日期</th><th>饮水量 (ml)</th></tr></thead><tbodyid="table-month-view-body"></tbody></table></div>这段 HTML 定义了月视图统计页面的基础结构。与周视图类似,表格的每一行展示某一天的总饮水量。标题明确标注“本月喝水统计”,让用户清楚当前查看的是哪个时间范围的数据。tbody使用table-month-view-body作为占位符,在 JavaScript 中动态插入行数据。由于一个月可能有 28~31 天,表格行数会随之变化。
.page-month-view{padding:16px 24px;}#table-month-view td:nth-child(2){text-align:right;}CSS 部分延续了之前的风格:为页面增加统一的内边距,并将第二列(饮水量列)右对齐。注意到无论是周视图还是月视图,布局风格都保持一致,这有助于用户在不同统计页面之间切换时保持认知连贯性。
三、计算当月日期并聚合统计
functiongetCurrentMonthDays(){consttoday=newDate();constyear=today.getFullYear();constmonth=today.getMonth();constdays=[];constfirstDay=newDate(year,month,1);letcurrent=newDate(firstDay);while(current.getMonth()===month){days.push(newDate(current));current.setDate(current.getDate()+1);}returndays;}getCurrentMonthDays函数用于生成当前月份中每一天的日期对象列表。从每月第一天开始,逐日递增,直到月份发生变化为止。这种写法确保了无论当月是 28、29、30 还是 31 天,都能准确生成所有日期。与周视图类似,即便某些天没有喝水记录,也可以在界面上显示 0 ml,从而帮助用户识别自己在整个月度中的习惯空白。
asyncfunctionloadMonthView(){constdays=getCurrentMonthDays();consttbody=document.getElementById('table-month-view-body');if(!tbody)return;tbody.innerHTML='';conststatsForNative=[];for(constdofdays){conststart=newDate(d.getFullYear(),d.getMonth(),d.getDate());constend=newDate(start);end.setDate(start.getDate()+1);consttotal=awaitdb.getTotalAmountBetween(start,end);consttr=document.createElement('tr');consttdDate=document.createElement('td');consttdAmount=document.createElement('td');tdDate.textContent=start.toISOString().slice(0,10);tdAmount.textContent=`${total}`;tr.appendChild(tdDate);tr.appendChild(tdAmount);tbody.appendChild(tr);statsForNative.push({date:tdDate.textContent,total});}syncMonthViewToNative(statsForNative);}loadMonthView函数负责根据当月所有日期从 IndexedDB 中聚合统计数据,并渲染到表格中。对每一天,构造[start, end)区间,并调用db.getTotalAmountBetween获取该天总饮水量,然后创建表格行、填入日期和数值,追加到tbody。同时,将{ date, total }结构加入statsForNative数组,最后通过syncMonthViewToNative统一发送给 ArkTS 插件。这种模式与周视图高度一致,有利于在代码层面保持统一风格,降低维护成本。
document.addEventListener('DOMContentLoaded',()=>{loadMonthView();});在DOMContentLoaded事件中触发loadMonthView,确保页面结构加载完成后再执行统计操作。由于月视图涉及的天数更多,统计过程会比周视图略慢,但只要 IndexedDB 访问实现合理,依然可以满足日常使用场景的性能要求。
四、通过 Cordova 将月视图数据同步给原生
functionsyncMonthViewToNative(items){if(!window.cordova){console.warn('[MonthView] cordova not ready, skip native sync');return;}cordova.exec(()=>{console.info('[MonthView] sync month data success');},(err)=>{console.error('[MonthView] sync month data failed',err);},'WaterTrackerMonthView','setMonthData',[items]);}syncMonthViewToNative函数与周视图对应函数类似,只是插件名称与动作名称不同。这里使用WaterTrackerMonthView插件和setMonthData动作,将当前月份的每日统计数据数组发送给 ArkTS 侧。原生层可以根据这份数据构建多种 UI 展示形式,例如月度热力图、折线图等,帮助用户从长期维度观察饮水习惯。
五、OpenHarmony ArkTS 插件与月度数据缓存
// entry/src/main/ets/plugins/WaterTrackerMonthViewPlugin.etsimportcommonfrom'@ohos.app.ability.common';exportinterfaceMonthDayStat{date?:string;total:number;}exportclassMonthViewStore{privatestatic_items:MonthDayStat[]=[];staticsetItems(items:MonthDayStat[]){this._items=items;}staticgetitems(){returnthis._items;}}exportdefaultclassWaterTrackerMonthViewPlugin{context:common.UIAbilityContext;constructor(ctx:common.UIAbilityContext){this.context=ctx;}setMonthData(args:Array<Object>,callbackId:number){constitems=args[0]asMonthDayStat[];MonthViewStore.setItems(items);console.info(`[MonthViewPlugin] receive${items.length}days`);}}这段 ArkTS 代码定义了月视图插件和存储类。MonthDayStat接口定义了每日统计对象结构,包含日期与总饮水量两个字段。MonthViewStore使用静态数组_items缓存当前月份所有天的统计数据,并提供setItems和items访问器用于更新与读取。插件类WaterTrackerMonthViewPlugin在setMonthData方法中解析args[0]为数组,存入MonthViewStore后输出日志说明收到的天数。这种模式与周视图插件高度一致,便于在不同时间维度间复用思路。
六、ArkUI 中展示月度概览
// entry/src/main/ets/pages/MonthViewPage.etsimport{MonthViewStore}from'../plugins/WaterTrackerMonthViewPlugin';@Component struct MonthViewStats{build(){Column(){Text('本月喝水统计').fontSize(18).margin({bottom:8});MonthViewStore.items.forEach((item)=>{Row(){Text(item.date||'').fontSize(14);Text(`${item.total}ml`).fontSize(14).margin({left:8});}.margin({bottom:4});});}.padding(16)}}MonthViewStatsArkUI 组件展示了如何在原生侧消费MonthViewStore.items中的月度统计数据。组件在build方法中遍历每一天的统计对象,为其创建一行包含日期和总饮水量的Row。尽管这里仍是文本列表形式,但它已经可以帮助用户在原生页面中快速浏览本月每一天的喝水情况。在未来扩展中,你可以将这些数据与图表控件结合,或者在桌面卡片中以精简形式呈现部分信息。
七、小结
通过本篇文章,我们实现了“月视图统计”功能在 Cordova&openharmony 混合应用中的基础架构:Web 层通过getCurrentMonthDays与loadMonthView计算本月每日总饮水量并渲染表格,同时使用syncMonthViewToNative将统计结果同步到 ArkTS 插件;OpenHarmony 端使用MonthViewStore和WaterTrackerMonthViewPlugin缓存这些数据,并在 ArkUI 组件MonthViewStats中为用户提供原生侧的月度概览视图。
文章沿用一小段代码一小段说明的写法,目的是让每一步的职责和数据流向都清晰可见,避免出现难以阅读的大段代码。你可以在此基础上进一步加入历史月份切换、与目标完成度的对比显示、以及更高级的趋势分析算法,将“月视图统计”打造为长期习惯分析的重要入口。