《仿盒马》app开发技术分享-- 个人中心页or静态头像选择(业务逻辑)(22)

举报
yd_215151764 发表于 2025/06/30 10:26:44 2025/06/30
【摘要】 ## 技术栈Appgallery connect## 开发准备上一节我们实现了登录页面的业务逻辑,并且成功的实现了数据的查询,同时我们新增了用户首选项的工具类,现在主界面往登录页面跳转,登录成功后我们关闭登录页面,这时候我们就会回到个人中心页面,那么现在我们的业务逻辑是一种什么样的形式?登录成功后我们需要显示用户的信息,并且在下次登录时依旧展示个人信息。同时我们还新增了一个头像选择的静态弹窗...


## 技术栈

Appgallery connect
## 开发准备

上一节我们实现了登录页面的业务逻辑,并且成功的实现了数据的查询,同时我们新增了用户首选项的工具类,现在主界面往登录页面跳转,登录成功后我们关闭登录页面,这时候我们就会回到个人中心页面,那么现在我们的业务逻辑是一种什么样的形式?登录成功后我们需要显示用户的信息,并且在下次登录时依旧展示个人信息。同时我们还新增了一个头像选择的静态弹窗,丰富个人信息页面

## 功能分析
我们需要注意的问题有如下几个:
1.tabs 切换的时候自定义组件是不会刷新的,所以需要处理切换时每次的刷新问题
2.切换到个人中心页面时加载登录时的用户信息
3.点击头像唤起自定义头像选择弹窗


## 代码实现

首先在登录的时候保存内容以及传递用户信息
 StorageUtils.set("user",JSON.stringify(data1[0]))
          router.back({
            url: 'pages/Index',
            params: {
              info: user
            }
          });
然后解决切换时自定义组件不刷新的问题,我们在index页面定义一个下标的tag ,然后通过@prop 传进组件内,通过监听来执行我们想要的方法
 @State currentIndexCheck: number = 3
  @Prop @Watch("onRefresh") currentIndex:number=0
   async onRefresh(): Promise<void> {
   }
 
 现在我们切换的问题解决了,接下来要解决的是数据的传输,在上方的back中我们把用户信息传递到了index页面,所以我们需要接收一下
 
  onPageShow(): void {
    const params = this.getUIContext().getRouter().getParams() as User;
    if (params) {
      const info: User = params as User;
      if (info!=null) {
        this.controller.changeIndex(3);
        this.user=info
      }
    }
  }

通过@Provide   @Consume 来实现数据的传递

首页定义
  @Provide user: User|null=null

个人中心页定义
@Consume user: User|null;

个人中心页面刷新用户数据
async onRefresh(): Promise<void> {
    if (this.currentIndexCheck==this.currentIndex) {
      const value = await StorageUtils.getAll('user');
      this.user=JSON.parse(value)
    }
  }

   
   填充对应的数据
    if (this.user!=null) {
            Row() {
              Image($r('app.media.background'))
                .height(55)
                .width(55)
                .borderRadius(27)
                .objectFit(ImageFit.Contain)
                .interpolation(ImageInterpolation.High)
                .onClick(()=>{
                  this.dialogController.open()
                })
              Column() {
                Text(this.user!.user_name)
                  .fontSize(24)
                  .maxLines(1)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })
                Text(this.user!.is_vip?'svip':"开启vip")
                  .fontSize(14)
              }
              .alignItems(HorizontalAlign.Start)
              .margin({ left: 10 })
              Blank()
                .layoutWeight(1)
              Image($r('app.media.ic_arrow_bold'))
                .height(16)
                .width(16)
                .margin(20)
                .objectFit(ImageFit.Contain)
                .interpolation(ImageInterpolation.High)
            }
            .justifyContent(FlexAlign.Start)
            .margin({top: 30 })
          }
          到这里我们就实现了,用户信息每次登录都可以获取了


然后我们在点击头像的时候创建一个选择的弹窗,并且先把选择的头像路径返回出来

先定义弹窗并且填充数据

import { SplitLayoutModel } from "../entity/SplitLayoutModel";
import showToast from "../utils/ToastUtils";

@Preview
@CustomDialog
export struct HeadCheckDialog {
  controller: CustomDialogController;
  @Link str: string ;
  @State checkPos:number=-1
  @State headList:ESObject[]=[
    {'img':'在线图片链接'},
    {'img':'在线图片链接'},
    {'img':'在线图片链接'},
    {'img':'在线图片链接'},
    {'img':'在线图片链接'},
    {'img':'在线图片链接'}
  ]

  onItemSelected: (item: string) => void= () => {
  };

  build() {
    Column({space:20}) {
      Text("头像选择")
        .id('HeadPageHelloWorld')
        .fontSize($r('app.float.size_20'))
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.Black)
        .margin({top:20})

      Grid(){
        ForEach(this.headList,(item:ESObject,index:number)=>{
          GridItem(){
            Column(){
              Image(item.img)
                .width(80)
                .height(80)
                .onClick(()=>{
                  this.str=item.img
                  this.checkPos=index
                })
                .border({width:this.checkPos==index?2:0,color:this.checkPos==index?0xff0000:null})
                .borderRadius(20)
            }
          }
        })
      }
      .columnsGap(10)
      .rowsGap(10)
      .height(300)
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .width('90%')
      .padding(10)

      Text("确认")
        .width('50%')
        .textAlign(TextAlign.Center)
        .height(40)
        .fontSize(18)
        .fontColor(Color.White)
        .backgroundColor(0xff0000)
        .borderRadius(30)
        .margin({top:30})
        .onClick(()=>{
          if (this.str!='') {
            this.onItemSelected(this.str)
            // this.controller.close()
            showToast(this.str)
          }else {
            showToast("请先选择头像")
          }

        })
    }
    .borderRadius({topLeft:20,topRight:20})
    .justifyContent(FlexAlign.Start)

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

弹窗相关
 private dialogController: CustomDialogController = new CustomDialogController({
    builder: HeadCheckDialog({
      str:this.str,
      onItemSelected:(str)=>{
        showToast(str)
        this.str=str
      }
    }),
    alignment: DialogAlignment.Bottom,
    customStyle:true
  });

到这里已经实现了个人信息的展示和头像的静态选择

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。