const names =['张伟','王芳','李娜','刘强','陈军','杨洋','赵丽','黄勇','周雪','吴宇','徐鹏','马丽','孙建','朱敏','郭涛','曹梅','田亮','林静','范磊'];//随机抽取一个姓名
export function getRandomName(){
let randomIndex =Math.floor(Math.random()* names.length);return names[randomIndex];}//随机生成一个年龄
export function getRandomAge(){return10+Math.floor(Math.random()*30);}//随机生成一个手机号码
export function getRandomPhone(){const prefixArray =['130','131','132','133','134','135','136','137','138','139'];
let phone = prefixArray[Math.floor(Math.random()* prefixArray.length)];// 生成后8位随机数字for(let i =0; i <8; i++){
phone +=Math.floor(Math.random()*10);}return phone;}
2.3 ContactList.ets
import{ getRandomName, getRandomPhone } from '../../../../utils/RandomUtil';import{Person} from './model/DataModel';@Entry@Component
struct ContactsPage{// 初始化列表数据@State persons:Person[]=[newPerson(getRandomName(),getRandomPhone()),newPerson(getRandomName(),getRandomPhone())];// 点击名片展开的 id@State isOpenId: number =-1;// 是否选中@State isShowCheck:boolean=false;// 选中的名片 ID@State selectIdList: number[]=[];build(){Column(){//标题Row({ space:10}){Text('联系人').titleStyle()Blank()/**
* 通过 isShowCheck 控制 选择和取消 按钮的切换
*/Button(this.isShowCheck ?'取消':'选择').buttonStyle(Color.Gray).onClick(()=>{this.isShowCheck =!this.isShowCheck
})Button('+').buttonStyle(Color.Gray)/**
* 点击新增 新增联系人
*/.onClick(()=>{this.persons.push(newPerson(getRandomName(),getRandomPhone()))})}.width('100%').height(60)//列表List({ space:10}){ForEach(this.persons,(person:Person)=>{ListItem(){// 联系人组件ContactItem({
person: person,
isOpenId: $isOpenId,
isShowCheck:this.isShowCheck,
selectIdList: $selectIdList })}})}.width('100%').layoutWeight(1)//按钮if(this.isShowCheck){Button('删除').buttonStyle(Color.Red).margin({ top:10}).onClick(()=>{this.persons =this.persons.filter(person =>!this.selectIdList.includes(person.id));})}}.width('100%').height('100%').backgroundColor('#EFEFEF').padding(10)}}@Component
struct ContactItem{@ObjectLink person:Person;// 双向绑定父组件的 person 对象@State isShowPhone:boolean=false;// 定义是否展示 phone@Link@Watch("numberChanger") isOpenId: number;// 监听点击打开的名片 实现只能打开一个 再打开会关闭其他名片@Prop isShowCheck:boolean;// 接收父组件的值是否选中@Link selectIdList: number[]// 绑定父组件的选中 ID 列表/**
* 监听函数
* 监听当前选中的名片 id 是否为点击的名片 id
*/numberChanger(){this.person.id ==this.isOpenId ?this.isShowPhone =true:this.isShowPhone =false;}build(){Column(){Row({ space:10}){if(this.isShowCheck){Toggle({
type:ToggleType.Checkbox})/**
* 删除函数
* 当被选中时 将名片 id 添加到 绑定父组件的selectIdList中
* 当未选中时 移除绑定父组件的selectIdList中的 名片 id
*/.onChange((value)=>{
value ?this.selectIdList.push(this.person.id):this.selectIdList.slice(this.selectIdList.indexOf(this.person.id),1)})}//头像Image($r('app.media.img_user_avatar')).width(40).height(40)//姓名Text(this.person.name).fontSize(20).fontWeight(500)Blank()//收藏/**
* 双向绑定父组件的 person 对象中的 person.isStar 判断是否收藏
*/Image(this.person.isStar ? $r('app.media.ic_star_filled'): $r('app.media.ic_star_empty')).width(30).height(30).onClick(()=>{this.person.isStar =!this.person.isStar;})}.justifyContent(FlexAlign.SpaceBetween).padding(10).width("100%")/**
* 点击
* 1、改变展示名片 手机号
* 2、记录正在展示的名片 id 用于给 numberChanger() 监听函数判断是否是当前名片展开 如果是则关闭其他名片
*/.onClick(()=>{this.isShowPhone =!this.isShowPhone;this.isOpenId =this.person.id;})if(this.isShowPhone){Divider()Row(){Text(this.person.name).fontSize(20)Text(this.person.phone).fontSize(20).margin({ left:20})}.backgroundColor(Color.White).width('100%').height(70).padding(10).borderRadius(10)}}.backgroundColor(Color.White).padding(10).borderRadius(10)}}/**
* 一些 css 样式
*/@Extend(Text) function titleStyle(){.fontSize(30).fontWeight(500)}@Extend(Button) function buttonStyle(color:ResourceColor){.height(30).backgroundColor(color)}