鸿蒙应用ets之仿黑马智慧商城首页

黑马vue2项目的智慧商城,自己仿写一个鸿蒙版的


前言

需要用到黑马智慧商城接口。地址:wiki - 智慧商城-实战项目 (apifox.com)


一、使用ohpm下载三方库axios

具体教程在我之前天气预报文章查看如何使用

二、分析布局

 

纵向布局,除了头部的文字固定在顶部以外,其余的内容可以往下滑。

三、编写UI界面

1.顶部文字区

//顶部文字栏
          Row(){
            Text('鸿蒙智慧商城')
              .width('100%')
              .fontSize(25).fontWeight(800).fontColor(Color.White).textAlign(TextAlign.Center)
          }
          .width('100%').height('8%').backgroundColor("#c21401")

2.内容滚动区域 

1.搜索框

//搜索块
              Row(){
                Search({placeholder:'搜索你要找的商品'})
                  .width('90%')
              }.width('100%').justifyContent(FlexAlign.Center)

2.轮播图

 //轮播图
              Row(){
                Swiper(){
                  ForEach(this.swiperPicList,(item:string)=>{
                    Image(item)
                      .width('100%').height('20%')
                  })
                }.autoPlay(true)//设置自动播放
              }.width('100%')

 3.公告栏

//公告块
              Row(){
                Image(this.noticetUrl)
                  .width(30).height(30).margin({left:'2%'}).objectFit(ImageFit.Contain).borderRadius(10)
                //跑马灯组件
                Marquee({
                  start:true,
                  step:10,
                  loop:-1,
                  src:this.noticeText
                })
                  .fontSize(20).fontColor("#ffffff")
              }.width('100%').backgroundColor("#525252")

4.导航组

//导航组
              Row(){
                //网格布局,2行2列
                Grid(){
                  ForEach(this.navList,(item:any)=>{
                    GridItem(){
                      Column({space:10}){
                        Image(item.imgUrl)
                          .width(60).height(60)
                        Text(item.text)
                          .fontSize(14)
                      }
                    }
                  })
                }
                .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
                .rowsTemplate('1fr 1fr')
                .columnsGap(5)
                .rowsGap(5)
                .width('100%')
                .height(200)
              }.width('100%')

 5.广告图

//广告块
              Row(){
                Image(this.adPicUrl)
                  .width('100%').height('15%')
              }.width('100%')

6.文字信息

//文字提示块
              Row({space:20}){
                Divider().width('20%')
                Text('猜你喜欢').fontSize(17).fontWeight(600)
                Divider().width('20%')
              }.width('100%').justifyContent(FlexAlign.Center).margin({top:'5%'})
            

 7.商品区

//商品区
              Column({space:10}){
                ForEach(this.goodsList,(item:any)=>{
                  //组件和组件传值
                  goods({name:item.name,imgUrl:item.imgUrl,nowPrice:item.nowPrice,sales:item.sales})
                })
              }.width('100%').margin({top:'5%'})

8.商品组件

 获取父组件传递过来的值,使用@prop修饰器,单向传递

@Component
export struct goods{
   @Prop imgUrl:string
   @Prop name:string
   @Prop nowPrice:string
   @Prop sales:number

  build(){
    Row({space:30}){
      Image(this.imgUrl)
        .width('30%')
      Column(){
        // @ts-ignore
        Text(this.name).width('80%').fontSize(18)
        //当字体超过2行时候裁剪掉
        .maxLines(2).textOverflow({overflow:TextOverflow.Clip})
        Text('已售'+this.sales).fontSize(14).fontColor("#ffa9a9b3")
        Text(this.nowPrice).fontColor(Color.Red).fontWeight(700)

      }.width('70%').height('100%').justifyContent(FlexAlign.SpaceAround).alignItems(HorizontalAlign.Start)
    }.width('98%').height('20%').backgroundColor("#F6F6F6").padding('2%')
    .borderRadius(20).border({width:1})
  }
}

四 、发请求获取数据

由于要获取多个数据,我么为了减少代码重复性,可以写一个通用函数

代码中包含了每条的注释,结合黑马官方接口文档,获取并赋值

async getHomeData() {
    try {
      // 发起API请求获取数据
      const data = await axios.get('http://cba.itlike.com/public/index.php?s=/api//page/detail');

      // 处理数据项的通用函数
      const processItems = (index, callback) => {
        const items = data.data.data.pageData.items[index].data;
        items.forEach(item => callback(item));
      };

      // 处理轮播图数据
      processItems(1, item => this.swiperPicList.push(item.imgUrl));

      // 设置通知文本
      this.noticeText = data.data.data.pageData.items[2].params.text;

      // 处理导航列表数据
      processItems(3, item => {
        this.navList.push({
          imgUrl: item.imgUrl,
          text: item.text
        });
      });

      // 设置广告图URL
      this.adPicUrl = data.data.data.pageData.items[4].data[0].imgUrl;

      // 处理商品信息数据
      processItems(6, item => {
        this.goodsList.push({
          name: item.goods_name,
          imgUrl: item.goods_image,
          nowPrice: item.goods_price_min,
          sales: item.goods_sales
        });
      });

      // 标记数据准备完毕
      this.isGo = true;
    } catch (error) {
      // 捕获并输出错误信息
      console.error('发生错误:', error);
    }
  }

总结

1.说明

首页内容通过get请求获取数据,该接口包含较多的数组内容,赋值一定要对着接口数据来获取,获取后对变量进行赋值,再根据界面仿写UI界面即可。

可以添加一个等待获取数据效果,即在根容器上使用stack堆叠容器,默认为展示,当获取完接口数据之后,在对标志赋值,取消展示等待效果

2.完整代码

import axios from '@ohos/axios'
import { goods } from '../components/goods'

@Component
export struct Home{

  //轮播图数组
  @State swiperPicList:string[]=['https://tse1-mm.cn.bing.net/th/id/OIP-C.QdPHAPCpK8VeGsRtXlKLBQHaEK?w=318&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7']
  //公告图标网址
  @State noticetUrl:string = 'https://tse1-mm.cn.bing.net/th/id/OIP-C.St8yQ-b9wkJKYtbSZldSzgAAAA?w=176&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7'
  //公告文字
  @State noticeText:string = ''
  //导航数组
  @State navList:any[] = []
  //广告图片网址
  @State adPicUrl:string = ''
  //商品信息数组
  @State goodsList:any[] = []
  //数据加载完标志
  @State isGo:boolean = false

  aboutToAppear(){
      this.getHomeData()
  }

  async getHomeData() {
    try {
      // 发起API请求获取数据
      const data = await axios.get('http://cba.itlike.com/public/index.php?s=/api//page/detail');

      // 处理数据项的通用函数
      const processItems = (index, callback) => {
        const items = data.data.data.pageData.items[index].data;
        items.forEach(item => callback(item));
      };

      // 处理轮播图数据
      processItems(1, item => this.swiperPicList.push(item.imgUrl));

      // 设置通知文本
      this.noticeText = data.data.data.pageData.items[2].params.text;

      // 处理导航列表数据
      processItems(3, item => {
        this.navList.push({
          imgUrl: item.imgUrl,
          text: item.text
        });
      });

      // 设置广告图URL
      this.adPicUrl = data.data.data.pageData.items[4].data[0].imgUrl;

      // 处理商品信息数据
      processItems(6, item => {
        this.goodsList.push({
          name: item.goods_name,
          imgUrl: item.goods_image,
          nowPrice: item.goods_price_min,
          sales: item.goods_sales
        });
      });

      // 标记数据准备完毕
      this.isGo = true;
    } catch (error) {
      // 捕获并输出错误信息
      console.error('发生错误:', error);
    }
  }


  build(){
    //层叠布局
    Stack(){
      if(!this.isGo){
        LoadingProgress()
        Text('加载数据中')
      }else {
        Column({space:10}){
          //顶部文字栏
          Row(){
            Text('鸿蒙智慧商城')
              .width('100%')
              .fontSize(25).fontWeight(800).fontColor(Color.White).textAlign(TextAlign.Center)
          }
          .width('100%').height('8%').backgroundColor("#c21401")
          //滚动容器
          Scroll() {
            Column() {
              //搜索块
              Row(){
                Search({placeholder:'搜索你要找的商品'})
                  .width('90%')
              }.width('100%').justifyContent(FlexAlign.Center)
              //轮播图
              Row(){
                Swiper(){
                  ForEach(this.swiperPicList,(item:string)=>{
                    Image(item)
                      .width('100%').height('20%')
                  })
                }.autoPlay(true)//设置自动播放
              }.width('100%')
              //公告块
              Row(){
                Image(this.noticetUrl)
                  .width(30).height(30).margin({left:'2%'}).objectFit(ImageFit.Contain).borderRadius(10)
                //跑马灯组件
                Marquee({
                  start:true,
                  step:10,
                  loop:-1,
                  src:this.noticeText
                })
                  .fontSize(20).fontColor("#ffffff")
              }.width('100%').backgroundColor("#525252")
              //导航组
              Row(){
                //网格布局,2行2列
                Grid(){
                  ForEach(this.navList,(item:any)=>{
                    GridItem(){
                      Column({space:10}){
                        Image(item.imgUrl)
                          .width(60).height(60)
                        Text(item.text)
                          .fontSize(14)
                      }
                    }
                  })
                }
                .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
                .rowsTemplate('1fr 1fr')
                .columnsGap(5)
                .rowsGap(5)
                .width('100%')
                .height(200)
              }.width('100%')
              //广告块
              Row(){
                Image(this.adPicUrl)
                  .width('100%').height('15%')
              }.width('100%')
              //文字提示块
              Row({space:20}){
                Divider().width('20%')
                Text('猜你喜欢').fontSize(17).fontWeight(600)
                Divider().width('20%')
              }.width('100%').justifyContent(FlexAlign.Center).margin({top:'5%'})
              //商品区
              Column({space:10}){
                ForEach(this.goodsList,(item:any)=>{
                  //组件和组件传值
                  goods({name:item.name,imgUrl:item.imgUrl,nowPrice:item.nowPrice,sales:item.sales})
                })
              }.width('100%').margin({top:'5%'})
            }.width('100%')
          }.width('100%').height('92%').scrollBar(BarState.Off)//不显示滚动条
        }
        .width('100%').height('100%')
      }

    }

  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值