# 評論頁面小demo
## 效果展示

## 1.拆解組件,分層搭建
我們將整個評論頁面拆解為三個組件,分別是頭部導(dǎo)航,評論項,回復(fù)三個部分,然后統(tǒng)一在index界面導(dǎo)入

## 2.頭部導(dǎo)航界面搭建

```ts
@Preview
@Component
struct HmNavBar {
// 屬性:是可以被傳遞值進行替換的
build() {
Stack({ alignContent: Alignment.Start }) {
Row() {
Image($r('sys.media.ohos_ic_compnent_titlebar_back'))
.width('100%')
.aspectRatio(1)
}.width(24)
.padding(4)
.borderRadius(12)
.backgroundColor('#f5f7f8')
Text('評論回復(fù)')//先設(shè)置占頁面的100% 然后在居中對齊
.width('100%')
.textAlign(TextAlign.Center)
}
.width('100%')
.padding(20)
}
}
export { HmNavBar }
```
* 上述UI界面搭建很簡單,但要注意一點就是在有了返回按鈕的情況下如何讓評論回復(fù)在整行居中,我們可以采用Stack布局,或者是在右邊也放置一個寬度為24的容器
## 3.評論項搭建

```ts
@Preview
@Component
struct HmReplay {
build() {
Row({ space: 8 }) {
Image($r('app.media.Cover1'))
.width(60)
.borderRadius(30)
Column({ space: 5 }) {
Text('遇到困難睡大覺')
.fontSize(18)
.fontWeight(700)
Text('你已經(jīng)是一個成熟的評論了要學(xué)會自己打破零回復(fù)!')
.fontSize(18)
Row() {
Row() {
Text('10-21.IP 屬地安徽')
.fontColor('#ffcfcfcf')
}
Row({ space: 5 }) {
Image($r('app.media.love'))
.width(24)
.aspectRatio(1)
Text('100')
.fontColor('#ffcfcfcf')
}
}.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}.width('100%')
.padding(20)
.height(120)
.alignItems(VerticalAlign.Top)
}
}
export { HmReplay }
```
## 4.評論列表搭建
### 4.1.1分割線+回復(fù) 部分
```ts
Row() {
Text('回復(fù) (7)')
}.padding(12)
.border({
width: {
top: 6
},
color: 'rgb(246,246,246)'
})
.width('100%')
```
### 4.1.2 評論列表
#### 1.導(dǎo)入對應(yīng)的數(shù)據(jù)結(jié)構(gòu)
```ts
@State commentList: ReplyItemModel[] = [
new ReplyItemModel({
id: 1,
avatar: 'https://picx.zhimg.com/027729d02bdf060e24973c3726fea9da_l.jpg?source=06d4cd63',
author: '偏執(zhí)狂-妄想家',
content: '更何況還分到一個摩洛哥[驚喜]',
time: '11-30',
area: '海南',
likeNum: 34,
likeFlag: false
}),
new ReplyItemModel({
id: 2,
avatar: 'https://pic1.zhimg.com/v2-5a3f5190369ae59c12bee33abfe0c5cc_xl.jpg?source=32738c0c',
author: 'William',
content: '當年希臘可是把1:0發(fā)揮到極致了',
time: '11-29',
area: '北京',
likeNum: 58,
likeFlag: false
}),
new ReplyItemModel({
id: 3,
avatar: 'https://picx.zhimg.com/v2-e6f4605c16e4378572a96dad7eaaf2b0_l.jpg?source=06d4cd63',
author: 'Andy Garcia',
content: '歐洲杯其實16隊球隊打正賽已經(jīng)差不多,24隊打正賽意味著正賽階段在小組賽一樣有弱隊。',
time: '11-28',
area: '上海',
likeNum: 10,
likeFlag: false
}),
new ReplyItemModel({
id: 4,
avatar: 'https://picx.zhimg.com/v2-53e7cf84228e26f419d924c2bf8d5d70_l.jpg?source=06d4cd63',
author: '正宗好魚頭',
content: '確實眼紅啊,亞洲就沒這種球隊,讓中國隊刷',
time: '11-27',
area: '香港',
likeNum: 139,
likeFlag: false
}),
new ReplyItemModel({
id: 5,
avatar: 'https://pic1.zhimg.com/v2-eeddfaae049df2a407ff37540894c8ce_l.jpg?source=06d4cd63',
author: '柱子哥',
content: '我是支持擴大的,亞洲杯歐洲杯擴到32隊,世界杯擴到64隊才是好的,世界上有超過200支隊伍,歐洲區(qū)55支隊伍,亞洲區(qū)47支隊伍,即使如此也就六成出現(xiàn)率',
time: '11-27',
area: '舊金山',
likeNum: 29,
likeFlag: false
}),
new ReplyItemModel({
id: 6,
avatar: 'https://picx.zhimg.com/v2-fab3da929232ae911e92bf8137d11f3a_l.jpg?source=06d4cd63',
author: '飛軒逸',
content: '禁止歐洲杯擴軍之前,應(yīng)該先禁止世界杯擴軍,或者至少把亞洲名額一半給歐洲。',
time: '11-26',
area: '里約',
likeNum: 100,
likeFlag: false
})
]
//先定義一個接口 然后可以使用接口轉(zhuǎn)換工具轉(zhuǎn)換成對應(yīng)的類
export interface ReplyItem {
avatar: ResourceStr // 頭像
author: string // 作者
id: number // 評論的id
content: string // 評論內(nèi)容
time: string // 發(fā)表時間
area: string // 地區(qū)
likeNum: number // 點贊數(shù)量
likeFlag: boolean | null // 當前用戶是否點過贊
}
export class ReplyItemModel implements ReplyItem {
avatar: ResourceStr = ''
author: string = ''
id: number = 0
content: string = ''
time: string = ''
area: string = ''
likeNum: number = 0
likeFlag: boolean | null = null
constructor(model: ReplyItem) {
this.avatar = model.avatar
this.author = model.author
this.id = model.id
this.content = model.content
this.time = model.time
this.area = model.area
this.likeNum = model.likeNum
this.likeFlag = model.likeFlag
}
}
```
#### 4.搭建評論列表界面
```ts
List() {
ForEach(this.commentList, (item: ReplyItemModel) => {
ListItem() {
HmCommentItem({
commentInfo: item,
//但凡傳函數(shù)吧必須用箭頭函數(shù)包裹!
changeLike:(id:number)=>{
this.changeLike(id)
}
})
}
})
}.layoutWeight(1)
```
* 這里需要注意幾點
1. List里面必須放置`ListItem()`
2. 評論列表的高度可以給一個自適應(yīng),這樣可以讓列列表超出屏幕的高度時實現(xiàn)自適應(yīng)
## 5.點贊邏輯的實現(xiàn)
實現(xiàn)任務(wù):當我們點擊愛心或者點贊的時候,點贊數(shù)量+1,愛心變位紅色,當我們再次點擊,點贊由原來的點贊變?yōu)槿∠c贊,愛心的顏色變?yōu)榛疑c贊的數(shù)量-1
代碼層面分析:由于我們顯示的數(shù)據(jù)是由主界面?zhèn)鞯阶咏缑娴模晕覀冃枰诟附缑娑x一個方法,傳遞到子面去,在子界面去調(diào)用這個方法,所以在子界面需要有一個接受的方法
### 5.1.1 子界面接收的方法
```ts
changeLike:(id:number)=>void = ()=> {
}
```
### 5.1.2 點贊業(yè)務(wù)邏輯的實現(xiàn)
```ts
//點贊邏輯處理
changeLike(id:number){
//遍歷數(shù)組 對commentlist數(shù)組中的每一個元素item進行迭代
const index = this.commentList.findIndex(item =>item.id === id)
//分支處理主評論和回復(fù)評論點贊狀態(tài)
if(index < 0){//處理主評論
if(this.comment.likeFlag){//已經(jīng)點贊
this.comment.likeNum -- //點贊數(shù)量--
}else {//未點贊
//點贊數(shù)量++
this.comment.likeNum++
}
this.comment.likeFlag = !this.comment.likeFlag
}else{//處理回復(fù)評論 找到回復(fù)列表中的某一個子評論
//返回第一次匹配元素的數(shù)組索引(0~N)
if(this.commentList[index].likeFlag){
this.commentList[index].likeNum--
}else {
this.commentList[index].likeNum++
}
this.commentList[index].likeFlag = !this.commentList[index].likeFlag
//@State修飾的數(shù)據(jù)只能監(jiān)聽到第一層或者本身 需要new一下在使用
this.commentList[index] = new ReplyItemModel(this.commentList[index])
// this.commentList.splice(index,1,this.commentList[index])
}
```
### 5.1.3父界面進行傳值

## 6.發(fā)布界面的搭建
### 6.1.1 發(fā)布的邏輯
```ts
publishComment(content:string){
this.commentList.unshift(new ReplyItemModel({
// id: Math.random()的作用是生成一個基于隨機數(shù)的臨時唯一標識,但需注意:
// 數(shù)值范圍: 0 ≤ N < 1 (浮點數(shù))
// 格式示例: 0.1234567890123456
// 非整型: 生成16位小數(shù)的浮點數(shù)
//id不能重復(fù)
id: Math.random(),
avatar: 'https://picx.zhimg.com/027729d02bdf060e24973c3726fea9da_l.jpg?source=06d4cd63',
author: '遇到困難睡大覺',
content: '山外青山樓外樓,不回消息我記仇',
time: '11-30',
area: '安徽',
likeNum: 0,
likeFlag: false
}))
}
```
### 6.1.2 發(fā)布界面
```ts
@Preview
@Component
struct replay {
content: string = ''
@Link
conmentsnum: number
publish: (content: string) => void = () => {
}
build() {
Row() {
TextInput({ placeholder: '請留下你的評論~', text: $$this.content })
.layoutWeight(1)
.onSubmit(() => {
this.publish(this.content)
this.content = ''
})
Button('發(fā)布')
.onClick(() => {
this.publish(this.content)
this.content = ''
this.conmentsnum++
})
}
.width('100%')
.padding(12)
}
}
export { replay }
```
審核編輯 黃宇
-
Harmony
+關(guān)注
關(guān)注
0文章
63瀏覽量
2870
發(fā)布評論請先 登錄
harmony OS NEXT-雙向數(shù)據(jù)綁定MVVM以及$$語法糖介紹
harmony OS NEXT-通過用戶首選項實現(xiàn)數(shù)據(jù)持久化
harmony OS NEXT-Navagation基本用法
Google Cloud Next 2025大會亮點回顧
HarmonyOS Next V2 @Local 和@Param

harmony OS NEXT-基本介紹及DevcoStudiop基本使用

HarmonyOS NEXT 原生應(yīng)用開發(fā):社交聊天對話過程實現(xiàn)
HarmonyOS NEXT 應(yīng)用開發(fā)練習(xí):AI智能對話框
HarmonyOS NEXT 應(yīng)用開發(fā)練習(xí):智能視頻推薦
不適用ADS8586S的過采樣功能,OS0,OS1,OS2這三個引腳該如何接?
峰岹demo板配套資料匯總
華為HarmonyOS NEXT 10月8日開啟公測

OpenAI宣布啟動GPT Next計劃
華為發(fā)布鴻蒙原生智能,OS深度融合AI,小藝升級為系統(tǒng)級智能體

HDC2024華為發(fā)布鴻蒙原生智能:AI與OS深度融合,開啟全新的AI時代

評論