HarmonyOS NEXT星河版之实战知乎App评论功能

文章目录

    • 一、目标完成页面
    • 二、实战
      • 2.1 定义数据
      • 2.2 mock数据
      • 2.3 封装顶部标题栏
      • 2.4 封装评论Item
      • 2.5 定义回复组件
      • 2.6 主页面
    • 三、小结

一、目标完成页面

在这里插入图片描述

二、实战

2.1 定义数据

export interface ReplyItem {
  avatar: ResourceStr // 头像
  author: string // 作者
  id: number // 评论的id
  content: string // 评论内容
  time: string // 发表时间
  area: string // 地区
  likeNum: number // 点赞数量
  likeFlag: boolean | null // 当前用户是否点过赞
}

export class ReplyItemModel implements ReplyItem {
  id: number = 0
  avatar: string | Resource = ''
  author: string = ''
  content: string = ''
  time: string = ''
  area: string = ''
  likeNum: number = 0
  likeFlag: boolean | null = null

  constructor(model: ReplyItem) {
    this.id = model.id
    this.avatar = model.avatar
    this.author = model.author
    this.content = model.content
    this.time = model.time
    this.area = model.area
    this.likeNum = model.likeNum
    this.likeFlag = model.likeFlag
  }
}
export enum CommentType {
  MAIN,// 顶部
  NORMAL// 普通
}

2.2 mock数据

export const mockReplyList: ReplyItemModel[] = [
  new ReplyItemModel({
    id: 1,
    avatar: 'https://picx.zhimg.com/027729d02bdf060e24973c3726fea9da_l.jpg?source=06d4cd63',
    author: '偏执狂-妄想家',
    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发挥到极致了',
    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队球队打正赛已经差不多,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支队伍,欧洲区55支队伍,亚洲区47支队伍,即使如此也就六成出现率',
    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: '禁止欧洲杯扩军之前,应该先禁止世界杯扩军,或者至少把亚洲名额一半给欧洲。',
    time: '11-26',
    area: '里约',
    likeNum: 100,
    likeFlag: false
  })
]

2.3 封装顶部标题栏

在这里插入图片描述
代码:

@Component
struct ZhiHuNavBar {
  title: string = '标题'

  build() {
    Stack({ alignContent: Alignment.Start }) {
      Row() {
        Image($r('app.media.ic_left_arrow'))
          .width(14)
          .margin({ left: 3 })
      }
      .height(30)
      .width(30)
      .borderRadius(15)
      .justifyContent(FlexAlign.Center)
      .zIndex(999)
      .backgroundColor(Color.Gray)

      Text(this.title)
        .width('100%')
        .textAlign(TextAlign.Center)
    }
    .width('100%')
    .height(50)
    .padding({ left: 20, right: 20 })
    .backgroundColor(Color.White)
    .border({
      color: '#e5e5e5',
      width: {
        bottom: 1
      }
    })
  }
}

export { ZhiHuNavBar }

2.4 封装评论Item

在这里插入图片描述
代码:

import { ReplyItem, ReplyItemModel } from '../models'

@Preview
@Component
struct ZhiHuComponentItem {
  @Prop item: ReplyItemModel = new ReplyItemModel({} as ReplyItem)
  changeLike: () => void = () => {
  }

  build() {
    Row({ space: 10 }) {
      Image(this.item.avatar)
        .width(28)
        .borderRadius(14)
      Column() {
        Text(this.item.author)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
        Text(this.item.content)
          .fontSize(13)
          .maxLines(3)
          .lineHeight(18)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .margin({ top: 8 })
          .padding({ bottom: 12 })
        Row({ space: 5 }) {
          Text(`${this.item.time} IP归属地${this.item.area}`)
            .fontSize(12)
            .fontColor('#999999')
          Row({ space: 3 }) {
            Image($r('app.media.ic_like'))
              .width(12)
              .fillColor(this.item.likeFlag ? Color.Red : Color.Black)
            Text(this.item.likeNum.toString())
              .fontSize(12)
              .fontColor('#999999')
          }
          .onClick(() => {
            this.changeLike()
          })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .alignItems(VerticalAlign.Top)
    .padding(20)
  }
}

export { ZhiHuComponentItem }

2.5 定义回复组件

在这里插入图片描述
代码:

@Component
struct ZhiHuReply {
  @State content: string = ''
  onSubmitContent: (content: string) => void = () => {
  }

  submitContent() {
    if (this.content) {
      this.onSubmitContent(this.content)
      this.content = ''
    }
  }

  build() {
    Row({ space: 15 }) {
      TextInput({ placeholder: '请输入', text: $$this.content })
        .layoutWeight(1)
        .height(40)
        .onSubmit(() => {
          this.submitContent()
        })
      Button('发布')
        .onClick(() => {
          this.submitContent()
        })
    }
    .height(60)
    .width('100%')
    .padding({
      left: 20,
      right: 20
    })
    .border({
      color: '#e5e5e5',
      width: {
        top: 1
      }
    })
  }
}

export { ZhiHuReply }

2.6 主页面

import { ZhiHuComponentItem, ZhiHuNavBar, ZhiHuReply } from './components'
import { mockReplyList, ReplyItemModel, ReplyItem, CommentType } from './models'

@Entry
@Component
struct ZhiHuDemoPage {
  @State commentList: ReplyItem[] = mockReplyList
  @State mainComment: ReplyItemModel = new ReplyItemModel({
    id: 999,
    author: '周杰伦',
    avatar: $r("app.media.zfb_pro_pic3"),
    likeNum: 10,
    likeFlag: false,
    time: '03-02',
    area: '北京',
    content: '人到了一定的年龄新陈代谢就慢了,吃了胖不吃瘦了皱纹就多,要靠锻炼 '
  })
  private scroller: Scroller = new Scroller()

  /**
   * 点赞or取消点赞
   * @param item
   * @param type
   */
  doChangeLike(item: ReplyItemModel, type?: CommentType) {
    if (item.likeFlag) {
      item.likeNum--
    } else {
      item.likeNum++
    }
    item.likeFlag = !item.likeFlag
    if (type === CommentType.MAIN) {
      this.mainComment = item
    } else {
      const index = this.commentList.findIndex(obj => obj.id === item.id)
      // this.commentList[index] = new ReplyItemModel(item)
      this.commentList.splice(index, 1, item)
    }
  }

  /**
   * 提交评论
   * @param content
   */
  onSubmitContent(content: string) {
    const replyItem = new ReplyItemModel({
      id: Math.random(),
      author: '李佳琦',
      avatar: $r("app.media.zfb_pro_pic3"),
      likeNum: 0,
      likeFlag: false,
      time: `${(new Date().getMonth() + 1).toString().padStart(2, '0')}-${new Date().getDate()}`,
      area: '上海',
      content
    })
    this.commentList.unshift(replyItem)
    this.scroller.scrollEdge(Edge.Top)
  }

  build() {
    Column() {
      // 标题栏
      ZhiHuNavBar({ title: '评论' })
      // 主评论
      ZhiHuComponentItem({
        item: this.mainComment,
        changeLike: () => {
          this.doChangeLike(this.mainComment, CommentType.MAIN)
        }
      })
      // 分割线
      Divider().strokeWidth(6)
      // 评论数
      Row() {
        Text(`评论数${this.commentList.length}`)
      }
      .width('100%')
      .height(50)
      .padding({ left: 20 })
      .border({
        color: '#f3f4f5',
        width: {
          bottom: 1
        }
      })
      // 普通评论列表
      List({ scroller: this.scroller }) {
        ForEach(this.commentList, (item: ReplyItemModel) => {
          ListItem() {
            ZhiHuComponentItem({
              item,
              changeLike: () => {
                this.doChangeLike(item)
              }
            })
          }
        })
      }
      .layoutWeight(1)

      // 回复模块
      ZhiHuReply({
        onSubmitContent: (content: string) => {
          this.onSubmitContent(content)
        }
      })

    }
    .height('100%')
    .width('100%')
    .backgroundColor(Color.White)
  }
}

三、小结

  • 组件拆分及布局
  • 父子组件数据传递
  • 父子组件事件传递
  • 数据更新及回调

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/547567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构|C语言版】顺序表应用

前言1. 基于动态顺序表实现通讯录1.1 通讯录功能1.2 代码实现1.2.1 SeqList.h1.2.2 SeqList.c1.2.3 Contact.h1.2.4 Contact.c1.2.5 test.c 1.3 控制台测试1.3.1 添加联系人1.3.2 删除联系人1.3.3 修改联系人1.3.4 查找联系人1.3.5 清空通讯录1.3.6 通讯录读档和存档 2. 好题测…

Day 41:动态规划 LeedCode 343. 整数拆分 96.不同的二叉搜索树

343. 整数拆分 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 思路: 1.确定dp数组&#xff0…

支付系统核心逻辑 — — 状态机(JavaGolang版本)

支付系统核心逻辑 — — 状态机 代码地址:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/state_machine_demo 1 概念:FSM(有限状态机),模式之间转换 状态机,也叫有限状态机&#xff08…

OpenWrt 多拨负载均衡不起作用

检查 负载均衡->规则->Https->粘滞模式 是否启动,设置为 否 如果设置为是,那么根据官方描述: 来自相同源 IP 的流量,如果已经匹配过此规则并且在粘滞超时时间内,将会使用相同的 WAN 接口 意思就是如果你同一个…

R语言 并行计算makeCluster报错

问题&#xff1a;使用parallel包进行并行计算&#xff0c; cl <- makeCluster(detectCores()) 出现以下问题&#xff1a; 解决方式&#xff1a;用makeClusterPSOCK命令代替即可 library("future") cl <- makeClusterPSOCK(124, revtunnel TRUE, outfile &…

【QT入门】Qt自定义控件与样式设计之自定义QTabWidget实现tab在左,文本水平的效果

往期回顾 【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件-CSDN博客 【QT入门】Qt自定义控件与样式设计之鼠标相对、绝对位置、窗口位置、控件位置-CSDN博客【QT入门】Qt自定义控件与样式设计之自定义QLineEdit实现搜索编辑框-CSDN博客 【QT入门】Qt自定义控件与样式…

(一)基于IDEA的JAVA基础16(end)

二维数组 二维数组就是数组里面再放一个数组 语法: <数据类型> [] [] 数组名&#xff1b; 或: <数据类型> 数组名 [] []&#xff1b; 比如这里有5个单位&#xff0c;每个单位员工有20个&#xff0c;他们都在忙几个相同的项目&#xff0c;现在要对某项项目进行操…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源&#xff0c;且作为作者的我不可修改为免费资源&#xff0c;不可删除&#xff0c;寻找客服无果&#xff0c;很愤怒&#xff0c;&#xff08;我发布免费资源就是希望大家能免费一起用、一起学习&#xff09;&#xff0c;接下来继续寻找…

Linux进阶篇:centos7搭建jdk环境

Linux服务搭建篇&#xff1a;centos7搭建jdk环境 本文主要介绍的是如何是Linux环境下安装JDK的&#xff0c;关于jdk的概念就不做赘述了&#xff0c;相信大家都有所耳闻了&#xff0c;Linux环境下&#xff0c;很多时候也离不开Java的&#xff0c;下面笔者就和大家一起分享如何jd…

【数据结构|C语言版】单链表应用

前言1. 基于单链表实现通讯录1.1 知识要求1.2 功能要求 2. 代码总结2.1 SeqList.h2.2 SeqList.c2.3 Contact.h2.4 Contact.c2.5 test.c 后言 上期回顾&#xff1a;【数据结构|C语言版】单链表 前言 各位小伙伴大家好&#xff01;上期小编讲解了单链表相关知识&#xff0c;在此…

SpringCloudAlibaba真的不行了吗?

Spring Cloud Alibaba 作为SpringCloudAlibaba微服务架构实战派上下册和RocketMQ消息中间件实战派上下册的作者胡弦&#xff0c;我想和技术人聊一下&#xff0c;阿里巴巴开源的SpringCloudAlibaba真的不行了吗&#xff1f; 目前SpringCloudAlibaba最新的版本为2023.0.0.0-RC1 …

蓝桥杯2024年第十五届省赛

E:宝石组合 根据给的公式化简后变为gcd(a,b,c)根据算数基本定理&#xff0c;推一下就可以了 然后我们对1到mx的树求约数&#xff0c;并记录约数的次数&#xff0c;我们选择一个最大的且次数大于等3的就是gcd int mx; vector<int> g[N]; vector<int> cnt[N]; int…

flutter material中的Icon组件的IconData 查阅

查阅 https://fonts.google.com/icons?selectedMaterialSymbolsOutlined:expand_less:FILL0;wght300;GRAD0;opsz24&icon.platformandroidhttps://fonts.google.com/icons?selectedMaterialSymbolsOutlined:expand_less:FILL0;wght300;GRAD0;opsz24&icon.platformand…

Java的maven项目导入本地jar包的三种方式

一、使用本地jar包 在项目中创建一个lib文件夹&#xff0c;将想要使用的本地jar包放进去 然后直接在pom.xml中添加下列依赖&#xff08;项目协作推荐&#xff09; <dependency><groupId>com.fpl</groupId><artifactId>spring</artifactId><…

Linux下SPI设备驱动实验:验证SPI节点及ICM20608设备子节点

一. 简介 前一篇文章在设备树文件中创建了SPI的 IO 的 pinctrl节点&#xff0c;SPI节点及ICM20608设备子节点&#xff0c;文章如下&#xff1a; Linux下SPI设备驱动实验&#xff1a;创建SPI节点及SPI设备子节点-CSDN博客 本文对设备树文件进行加载测试&#xff0c;确定SPI节…

leetcode199 二叉树的右视图

题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 解析 这道题首先能想到的办法&#xff0c;就是使用迭代法层次遍历&…

部署项目的时候的一些错误

项目打jar包&#xff0c;找不到资源&#xff0c;连接不上数据库 项目打包后无法运行 直接在idea运行可以 解决方法&#xff1a;pom文件中增加&#xff08;配置文件如果是yml&#xff0c;写yml&#xff09; <resources><resource><directory>src/main/java&…

系统学c#:2、基础语法(关键字、标识符、数据类型、变量、常量、字面量、运算符、类型转换)

关键字&#xff1a; 关键字是编程语言中具有特殊含义的单词或符号&#xff0c;它们通常被编程语言用于表示特定的语法结构、操作或约定。在C#中&#xff0c;关键字具有特定的语法和功能&#xff0c;用于定义语言的基本结构和规则。 以下是一些C#中常用的关键字及其功能&#xf…

【计算机毕业设计】游戏售卖网站——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

MybatisPlus——自定义Sql

MybatisPlus——自定义Sql 自定义sql mybatisplus自定义sql并不是全部进行自定义的&#xff0c;我们可以利用MybatisPlus的Wrapper来构建复杂的Where条件&#xff0c;然后自己定义sql语句中剩下的部分。 自定义sql案例 以为例&#xff1a;将id在指定范围&#xff08;1&…