☰
HarmonyOS 应用 · 室友评价评价页深度解析:四维星级打分与不可变更新
2026/10/4 7:22:15 网站建设 项目流程

HarmonyOS 应用 · 室友评价评价页深度解析:四维星级打分与不可变更新

项目编号:50-roommate-rate 技术栈:HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面:评价页Func1Tab.ets(104 行) 系列导航:(一)首页 ·(二)评价· (三)数据 · (四)我的


一、RateDim interface 与 scores 数组状态

interface RateDim { id: number; emoji: string; name: string; score: number; }

四个字段:id是 key 锚点,emoji是维度图标,name是维度名,score是默认分值。

@State activeMate: number = 0; @State scores: number[] = [5, 4, 5, 4]; private mates: string[] = ['阿强', '小明', '大伟']; private dims: RateDim[] = [ { id: 1, emoji: '🧹', name: '卫生习惯', score: 5 }, { id: 2, emoji: '🌙', name: '作息规律', score: 4 }, { id: 3, emoji: '🤝', name: '相处融洽', score: 5 }, { id: 4, emoji: '🔊', name: '安静程度', score: 4 } ];

两个@State:activeMate(选中室友索引)+scores(四维评分数组 [5,4,5,4])。mates是被评价室友(不含自己),dims是四个评价维度:卫生习惯/作息规律/相处融洽/安静程度。scores数组与dims数组索引对应——scores[0]是dims[0]的评分。


二、setScore:不可变更新触发星级刷新

private setScore(idx: number, s: number): void { this.scores[idx] = s; this.scores = this.scores.slice(); }

setScore(idx, s)两步不可变更新——先赋值scores[idx] = s,再slice()生成新引用触发@State刷新。与班级任务首页的toggle同款模式:直接修改数组元素不触发刷新,必须slice()换引用。


三、页面骨架:MateSelect + RateCard + CommentCard + Button

build() { Column() { this.Header() Scroll() { Column({ space: 16 }) { this.MateSelect() this.RateCard() this.CommentCard() Button('提交评价').fontSize(15).fontColor('#FFFFFF').backgroundColor(C.primary) .width('100%').height(48).borderRadius(D.rMd) .onClick(() => { promptAction.showToast({ message: '评价已提交' }); }) } .width('100%') .padding({ left: D.pad, right: D.pad, top: 16, bottom: D.pad + this.safeBottom + 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width('100%').height('100%').backgroundColor(C.bg) }

Header 在 Scroll 外固定,Scroll 内四块:MateSelect(室友选择)+ RateCard(评分卡)+ CommentCard(留言卡)+ Button(提交)。


四、MateSelect:activeMate 驱动的等分胶囊

@Builder MateSelect() { Row({ space: 10 }) { ForEach(this.mates, (m: string, idx: number) => { Text(m).fontSize(13) .fontColor(this.activeMate === idx ? '#FFFFFF' : C.textSub) .textAlign(TextAlign.Center).layoutWeight(1).padding({ top: 10, bottom: 10 }) .backgroundColor(this.activeMate === idx ? C.primary : C.card).borderRadius(D.rSm) .border({ width: 1, color: this.activeMate === idx ? C.primary : C.stroke }) .onClick(() => { this.activeMate = idx; }) }, (m: string) => m) }.width('100%') }

activeMate === idx驱动选中态:靛蓝底白字 + 靛蓝描边 vs 白底灰字 + 浅灰描边。三个室友等分,onClick设this.activeMate = idx切换被评价对象。


五、RateCard:嵌套 ForEach 星级打分

@Builder RateCard() { Column({ space: 16 }) { Text('评分维度').fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text).width('100%') ForEach(this.dims, (d: RateDim, dimIdx: number) => { Row({ space: 10 }) { Text(d.emoji).fontSize(20) Text(d.name).fontSize(14).fontColor(C.text).layoutWeight(1) Row({ space: 4 }) { ForEach([1, 2, 3, 4, 5], (star: number) => { Text(this.scores[dimIdx] >= star ? '⭐' : '☆').fontSize(16) .onClick(() => { this.setScore(dimIdx, star); }) }, (star: number) => star.toString()) } }.width('100%') }, (d: RateDim) => d.id.toString()) } .width('100%').padding(16).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke }) }

嵌套 ForEach——外层遍历维度,内层遍历 [1,2,3,4,5] 星级:

// 外层:4 个评价维度 ForEach(this.dims, (d: RateDim, dimIdx: number) => { // 内层:5 颗星 ForEach([1, 2, 3, 4, 5], (star: number) => { // scores[dimIdx] >= star → 实心星,否则空心星 Text(this.scores[dimIdx] >= star ? '⭐' : '☆') .onClick(() => { this.setScore(dimIdx, star); }) }) })

scores[dimIdx] >= star驱动实心/空心星——scores[0] = 5时 5 颗全实心,scores[1] = 4时前 4 颗实心 + 第 5 颗空心。点击第 3 颗星调setScore(dimIdx, 3)——scores[dimIdx]变 3,前 3 颗实心 + 后 2 颗空心。这是星级打分的经典实现:比较驱动渲染,点击驱动赋值。


六、CommentCard:TextArea 留言

@Builder CommentCard() { Column({ space: 10 }) { Text('评价留言').fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text).width('100%') TextArea({ placeholder: '写下对室友的评价...' }) .backgroundColor(C.cardSoft).borderRadius(D.rSm).height(90) } .width('100%').padding(16).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke }) }

TextArea多行输入,height(90)容纳多行评价文字。cardSoft浅灰底 +rSm小圆角。


七、可演进方向

方向现状改法收益
评价提交Toast 模拟写入评价记录 + 评分更新评价真实保存
室友切换scores 不重置切换时加载该室友已有评分切换不丢失数据
评分校验无至少一个维度打分才能提交评价完整性
留言绑定TextArea 无 onChange绑定 remark 状态留言随提交保存
多轮评价单次记录评价时间 + 历史追溯评价可回溯

评价页是室友评价的核心交互——activeMate驱动室友切换、嵌套 ForEach 实现星级打分、setScore的不可变更新触发星级刷新。从比较驱动的实心/空心星到slice()的数组刷新,每一层都有明确的职责边界。

系列导航:(一)首页 ·(二)评价· (三)数据 · (四)我的

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询