当前位置: 首页 > news >正文

万宁建设局网站地产渠道12种拓客方式

万宁建设局网站,地产渠道12种拓客方式,长春建设工程管理中心网站,绿色系的网站目录 前言 功能展示 整体页面布局 最新和最热 写评论 点赞功能 界面构建 初始数据的准备 列表项部分的渲染 底部区域 index部分 知识点概述 List组件 List组件简介 ListItem组件详解 ListItemGroup组件介绍 ForEach循环渲染 列表分割线设置 列表排列方向设…

 

目录

 前言

功能展示

整体页面布局

最新和最热 

写评论 

点赞功能 

界面构建

 初始数据的准备

 列表项部分的渲染

底部区域 

index部分 

 知识点概述

List组件

List组件简介

ListItem组件详解

ListItemGroup组件介绍

ForEach循环渲染

列表分割线设置

列表排列方向设置

索引值计算规则

@Prop装饰器 

@Prop注解的基本作用

@Prop注解的限制条件

@Prop注解的使用规则

@Prop注解的具体使用场景

全套代码

BottomCom部分

InfoCom部分

InfoItem部分

CommentDate部分

Index部分


个人主页→VON

收录专栏→鸿蒙开发小型案例总结​​​​​

基础语法部分会发布于github 和 gitee上面(暂未发布)

由于一些个人的特殊原因,基础部分的代码迟迟未进行上传,我会尽快进行整理发布后会第一时间进行通知,希望大家多多谅解

 前言

鸿蒙基础部分到这里也要和大家说再见了,此案例所用到的知识点众多构建过程较为复杂。希望读者们能够认真观看。我也会尽力帮助大家梳理代码以及各各部分的逻辑及其思路。

此案例可以应用于多个地方,比如博客,短视频app等都可以进行应用

功能展示

整体页面布局

整体分为三大部分,分别为头部、中间、底部。认真观察不难发现头部区域采用了Row,中间区域采用了List,底部区域采用了两个Row。整体布局为层叠布局。 

最新和最热 

 

最新和最热点击时显示的效果不同,并且列表所展示的也不同。点击最新时评论的内容会根据时间进行排序,最热时会根据点赞数进行排序。

写评论 

 自己可以在写评论处发布评论,列表会根据评论进行渲染。

点赞功能 

 

界面构建

由于代码的长度限制,过于基础的部分不在进行逐一讲解,希望大家谅解

 最新和最热是两个按钮组件,Extend装饰器进行修改,当未被选中时是一种状态,被选中时是另外一种状态。这两种状态的样式我是根据最左侧的颜色来进行适当调整的,大家也可以效仿。

 初始数据的准备

 初始数据是自己进行构建的一些数据,这些数据被打包在CommentDate中,其中点赞数和等级是随机的,其他部分都是自定义的。因为这是一个离线的静态页面,并没有实现交互功能所以目前只能这样来代替。

 列表项部分的渲染

渲染部分用到了CommentDate中的数据来进行逐一渲染的,因为实现交互的是子组件,但是要修改的部分是父组件的一些内容,所以对于可变的数据用到了Prop装饰器进行的装饰。 

底部区域 

底部区域实现了双向绑定,当输入评论并且单击回车键后数据会进行增加。并且会排在首位,也就是下标为0的位置增添了一个全新的数据。 

index部分 

 

一些函数的定义及其功能的实现全都在index页面来进行实现的,所以这一界面要尽量保持简介,每一部分都可以进行抽取单独进行ui界面的构建,通过import来进行导入即可。 

 知识点概述

List组件

鸿蒙开发中的List组件是一个功能强大且常用的UI组件,用于呈现连续的数据列表。

List组件简介

  • 基础定义:List组件是一种容器组件,用于展示一系列相同宽度的列表项,适合连续、多行呈现同类数据,例如图片和文本。
  • 参数配置:List组件接受三个主要参数:space(子组件主轴方向的间隔)、initialIndex(初次加载时视口起始位置显示的item索引)、scroller(可滚动组件的控制器)。

ListItem组件详解

  • 基本概念:ListItem是具体的列表项组件,必须配合List使用,用于展示每个具体的数据项。
  • 参数设置:主要参数包括selectable(是否可被鼠标框选)和swipeAction(设置划出组件的属性)。

ListItemGroup组件介绍

  • 功能描述:用于展示列表项分组,宽度默认充满List组件,也必须配合List使用。
  • 主要参数:header(头部组件)、footer(尾部组件)和space(列表项间距)。

ForEach循环渲染

  • 应用场景:当列表由多个相似或重复的列表项组成时,为减少代码冗余,可以使用ForEach进行循环渲染。
  • 工作原理:ForEach接口基于数组类型数据进行循环渲染,需与容器组件配合使用,如List。

列表分割线设置

  • 功能解释:通过divider属性设置列表项之间的分割线样式,提升视觉上的区分度和美观性。
  • 参数说明:主要参数包括strokeWidth(分割线的线宽)、color(分割线的颜色)、startMargin和endMargin(分割线距离列表侧边起始端和结束端的距离)。

列表排列方向设置

  • 垂直排列:List默认采用垂直排列方式,即列表项按垂直方向线性排列。
  • 水平排列:通过设置listDirection属性为Axis.Horizontal,可以实现列表项的水平排列。

索引值计算规则

  • 规则概述:索引值用来确定列表项在列表中的具体位置,初次加载时默认从0开始。
  • 细节掌握:初始索引可以通过initialIndex参数手动设置,但需确保索引值不超过列表项总数。

@Prop装饰器 

@Prop是一个方便的注解,用于在鸿蒙应用开发中实现组件之间的数据传递

在现代软件开发中,组件化和数据传递是提高开发效率和代码可维护性的关键环节。特别是在鸿蒙这类分布式操作系统中,对组件间数据传递机制的优化尤为重要。下面将详细探讨@Prop注解的作用、限制条件、使用规则以及具体的使用场景。

@Prop注解的基本作用

  • 单向数据同步:@Prop注解主要用于实现组件间的单向数据同步。这意味着,当父组件的状态发生改变时,这些改变会通过@Prop注解传递给子组件,但子组件对这些属性的修改不会影响到父组件。
  • 支持的数据类型:@Prop能够处理各种基本数据类型,包括字符串、数字、布尔值和枚举类型。这保证了其在不同场景下的灵活性和适用性。

@Prop注解的限制条件

  • 复杂类型的深拷贝:当@Prop涉及到复杂数据类型时(如对象或数组),会进行深拷贝操作。这一过程中,除了基本类型(如字符串、数字)、Map、Set、Date和Array外,其他类型可能会丢失。
  • 使用场景限制:@Prop不能在@Entry装饰的自定义组件中使用。这限定了@Prop的使用范围,通常仅适用于页面级组件。

@Prop注解的使用规则

  • 参数配置:@Prop不需要特定参数,其同步类型为单向同步。
  • 类型要求严格:使用@Prop时必须明确指定被装饰变量的具体类型,不允许使用any类型,也不允许使用undefined和null作为默认值。

@Prop注解的具体使用场景

  • 简单数据类型同步:例如,父组件中的@State状态可以通过@Prop注解传递给子组件。如果父组件的状态发生更新,子组件的@Prop也会相应更新。但如果子组件尝试修改这些属性,更改不会反映到父组件中。
  • 数组项同步:当父组件中的@State数组项更新时,子组件中对应的@Prop也会同步更新。例如,父组件可以包含一个数字数组,每个元素用来初始化子组件中的一个@Prop。同样,子组件对@Prop的修改不会反映到父组件中。
  • 类对象属性同步:父组件中的@State类对象可以用来初始化子组件的@Prop。任何父组件中对象属性的更新都会同步到子组件,但子组件对@Prop的修改依旧不会反向同步到父组件。

全套代码

BottomCom部分

@Component
struct BottomCom {@State txt:string=''onSubmitComment=(content:string)=>{}build() {Row(){Row(){Image($r('app.media.edit')).width(20).margin({left:10})TextInput({placeholder:'写评论...',// 双向绑定text:$$this.txt}).backgroundColor(Color.Transparent).fontSize(18)// 回车.onSubmit(()=>{this.onSubmitComment(this.txt)})}.height(40).backgroundColor('#f5f6f5').borderRadius(20).margin({left:15,right:20,top:10,bottom:10}).layoutWeight(1)Image($r('app.media.love_stare')).width(25)Image($r("app.media.like_stare")).width(25).margin({left:15,right:10})}.width('100%').height(60)}
}export default BottomCom

InfoCom部分

import BottomCom from './BottomCom'
@Extend(Button)
function ButStyle(click:boolean){.fontSize(12).border({width:1,color:click?'#fff':'#ffbeb7b7'}).width(46).height(32).padding({left:5,right:5}).fontColor(click ? '#80555858' :'#ff1f1e1e').backgroundColor(click ? '#fff' : '#1ae0e0e0')
}
@Component
struct InfoCom {@State click:boolean=trueonSort=(type:number)=>{}build() {Row(){Text('全部评论').fontSize(20).fontWeight(FontWeight.Bold)Row(){Button('最新').ButStyle(!this.click).onClick(()=>{this.click=truethis.onSort(0)})Button('最热').ButStyle(this.click).onClick(()=>{this.click=falsethis.onSort(1)})}}.justifyContent(FlexAlign.SpaceBetween).padding({left:20,right:20}).width('100%').height(60)}
}
export default InfoCom

InfoItem部分

import { CommentDate } from '../model/CommentDate'@Component
struct InfoItem {@Prop itemObj:CommentDate@Prop index:numberonLikeClick=(index:number)=>{}build() {// 列表项组件Column(){Row(){// 头像Image(this.itemObj.avatar).width(30).borderRadius(15).margin({top:10,right:5})// 昵称Text(this.itemObj.name).fontColor('#808d8585').fontSize(14).margin({top:10,left:5})// 等级Image(this.itemObj.levelIcon).width(20).margin({left:10,top:10})}// 评论内容Text(this.itemObj.commentext).fontSize(13).fontWeight(700).margin({top:10,left:40})Row(){// 时间Text(this.itemObj.timeString).fontSize(10).fontColor(Color.Gray)// 点赞Row(){Image(this.itemObj.islike ? $r('app.media.like_end') : $r('app.media.like_stare')).width(12)Text(this.itemObj.likenum.toString()).fontSize(10).fontColor(this.itemObj.islike ? Color.Red : Color.Gray)}.onClick(()=>{this.onLikeClick(this.index)})}.width('100%').padding({left:40,right:20,top:15}).justifyContent(FlexAlign.SpaceBetween)}.alignItems(HorizontalAlign.Start).padding({left:15,top:10})}
}export default InfoItem

CommentDate部分

// 准备评论数据类
export class CommentDate{avatar:ResourceStr;// 头像name:string;// 昵称level:number;// 用户等级likenum:number;// 点赞数量commentext:string;// 评论内容islike:boolean;// 是否喜欢levelIcon:Resource;// level等级timeString:string;// 发布时间time:number // 时间戳constructor(avatar: ResourceStr, name: string, level: number, likenum: number, commentext: string,islike: boolean,time:number) {this.avatar=avatarthis.name=namethis.level=levelthis.likenum=likenumthis.commentext=commentextthis.islike=islikethis.time=timethis.levelIcon=this.convertLevel(this.level)this.timeString=this.convertTime(time)}//时间转换函数convertTime(time:number){const currentTimestamp = new Date().getTime();// 转换为秒const timeDifference = (currentTimestamp-time)/1000;console.log(timeDifference.toString())if(timeDifference<0 || timeDifference==0){return '刚刚';}else if(timeDifference<60){return `${Math.floor(timeDifference)}秒前`;}else if(timeDifference<3600){return `${Math.floor(timeDifference/60)}分钟前`;}else if(timeDifference<86400){return `${Math.floor(timeDifference/3600)}小时前`;}else if(timeDifference<604800){return `${Math.floor(timeDifference/86400)}天前`;}else if(timeDifference<2592000){return `${Math.floor(timeDifference/604800)}周前`;}else if(timeDifference<31536000){return `${Math.floor(timeDifference/2592000)}个月前`;}else{return `${Math.floor(timeDifference/31536000)}年前`;}}// 等级图片获取convertLevel(Level:number){const iconList=[$r('app.media.lv1'),$r('app.media.lv2'),$r('app.media.lv3'),$r('app.media.lv4'),$r('app.media.lv5'),$r('app.media.lv6')]return iconList[Level]}
}// 封装一个方法,创建假数据
export const createListRange=():CommentDate[]=>{let result:CommentDate[]=new Array()result=[new CommentDate($r('app.media.tx_01'),'JohnYan',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'要是那天,我抓住你就好了',false,1705850201128),new CommentDate($r('app.media.tx_03'),'cv工程师',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'故事不长,也不难讲,相识一场,爱而不得',false,1643800201128),new CommentDate($r('app.media.tx_04'),'风行水上',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'后来啊,书没有读好,喜欢的人也没有在一起',false,1715850201128),new CommentDate($r('app.media.tx_05'),'枫以',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'你根本忘不了一个认认真真爱过的人,你以为错过的是一个人,其实你错过的是一整个人生',false,1680850201128),new CommentDate($r('app.media.tx_06'),'幼稚园里的幼稚鬼',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'有些伤痛即使已经痊愈,也会留下难以愈合的伤疤',false,1705850201128),new CommentDate($r('app.media.tx_07'),'浮临子',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'不是所有的梦想都会成真,不是所有的伤痛都能愈合,但我们要有勇气继续前行',false,1625050201128),new CommentDate($r('app.media.tx_08'),'╭⌒浅浅笑',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'孤独并不可怕,可怕的是渴望有人陪伴而得不到',false,1720850201128),new CommentDate($r('app.media.tx_09'),'枕头说它不想醒',Math.floor(Math.random()*6),Math.floor(Math.random()*100),'可惜爱不是写诗 我只能欲言又止',false,1745050201128)]return result
}

Index部分

import InfoCom from '../components/InfoCom'
import BottomCom from '../components/BottomCom'
import InfoItem from '../components/InfoItem'
import {CommentDate,createListRange} from '../model/CommentDate'@Entry
@Component
struct Index {// 处理点赞时的方法handlelike(index:number){// 要有唯一标识// AlertDialog.show({//   message:index.toString()// })// 父组件的方法,如果抽取出来,如果直接传递给子组件会有this指向问题,this通常直接指向调用者// 需要用箭头函数包一层,保证this还是指向父组件// 根据index进行判断let itemData=this.commentList[index]if(itemData.islike){itemData.likenum-=1}else{itemData.likenum+=1}itemData.islike= !itemData.islike// 对于复杂类型:状态对象,状态数组,只会对第一层数据进行监视变化this.commentList.splice(index,1,itemData)}// 处理提交handleSubmit(content:string){// 将数据添加到数组最前面const newItem:CommentDate=new CommentDate($r('app.media.tx_01'),'我',2,0,content,false,new Date().getTime())this.commentList=[newItem,...this.commentList]}// 处理排序handleSort(type:number){if(type==0){this.commentList.sort((a,b)=>{return b.time-a.time})}else if(type==1){this.commentList.sort((a,b)=>{return b.likenum-a.likenum})}}// 初始化数据@State commentList:CommentDate[]=createListRange()// 生命周期函数,会自动执行aboutToAppear(): void {this.handleSort(0)}build() {Column(){//头部InfoCom({onSort:(type:number)=>{this.handleSort(type)}})//中间List(){ForEach(this.commentList,(item:CommentDate,index:number)=>{ListItem(){// 列表项组件InfoItem({index:index,itemObj:item,onLikeClick:(index:number)=>{// 此处的this就是父组件this.handlelike(index)}})}})}.width('100%').layoutWeight(1)//底部BottomCom({onSubmitComment:(content:string)=>{this.handleSubmit(content)}})}.width('100%').height('100%')}
}

http://www.dinnco.com/news/45486.html

相关文章:

  • 做英语词汇测试的软件网站seo具体优化流程
  • 市政府网站建设工作情况汇报重庆seo网站推广优化
  • 视觉设计网站推荐百度问一问付费咨询
  • 网站有哪几种类型日本和韩国是亚洲的国家
  • 做外贸怎样上外国网站最好用的手机优化软件
  • 做教程网站资源放哪里谷歌推广怎么做
  • dz论坛怎么做视频网站网络推广费用大概价格
  • 深圳做网站的网络今日新闻头条10条
  • 搜狐快站做淘宝客网站武汉网站seo推广公司
  • 建设党建网站联盟seo网站查询
  • 刷网站建设惠州网站推广排名
  • wordpress 七牛视频教程2019网站seo
  • pageadmin自助建站如何推销自己的产品
  • 网站建设对接模版哪里有免费的网站推广
  • 英文网站如何做优化二十条
  • 做网站怎么租用服务器吗好用的网站推荐
  • 企业网站开发综合实训营销网络建设
  • 福建省建设工程职业注册网站网店推广的渠道有哪些
  • 网站建设使用的技术seo关键词排名报价
  • 个人网站可以做网上支付吗宁德市市长
  • 做b2b b2c型的混合网站地推接单在哪个平台找
  • 亚马逊网站建设做什么现在最火的发帖平台
  • 介绍婚纱网站的ppt怎么做中国培训网官网
  • 网站建设编程怎么写外贸订单怎样去寻找
  • 云表无代码开发平台搜索引擎优化自然排名的优点
  • 千万别去电商公司上班seo建站营销
  • 凡科网的网站建设怎么做b站好看的纪录片免费
  • 可以做3d电影网站百度登录
  • 如何生成网站宁德市委书记
  • 搜索网站建设百度搜索广告怎么收费