Harmony商城项目

发布于:2024-10-11 ⋅ 阅读:(95) ⋅ 点赞:(0)

1、启动项目看效果图

在这里插入图片描述

2、首页和购物车代码分析

2.1、首页代码分析


import CommonConstants from '../constants/CommonConstants';
import WomanPage from './components/WomanPage'
import ManPage from './components/ManPage'
import HomePage from './components/HomePage'
import SportPage from './components/SportPage'
import ComputerPage from './components/ComputerPage'
import Mine from './Mine'
import Shop from './Shop';


@Entry
@Component
struct MainPage {
//@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。
//在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。
//@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。
//@State装饰的变量拥有以下特点:
//@State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步,与@Link、@ObjectLink装饰变量之间建立双向数据同步。
//@State装饰的变量生命周期与其所属自定义组件的生命周期相同。

  @State currentIndex: number = CommonConstants.HOME_TAB_INDEX;
  @State changeValue: string = ''
  @State submitValue: string = ''

//TabsController
//Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。
//导入对象
//controller: TabsController = new TabsController()
  private tabController: TabsController = new TabsController()
  @State enableFlag : boolean = true;
  
//SearchController
//Search组件的控制器,目前通过它可控制Search组件的光标位置。
//导入对象
//controller: SearchController = new SearchController()
  searchController: SearchController = new SearchController()

  /*搜索框*/
  //@Builder装饰器:自定义构建函数
  @Builder SearchUI(){
    Row(){
      Search({ value: this.changeValue, placeholder: 'search...', controller: this.searchController })
        .searchButton('搜索')
        .width(CommonConstants.FULL_PARENT)
        .height(30)
        .backgroundColor('#F5F5F5')
        .placeholderColor(Color.Grey)
        .placeholderFont({ size: 14 , weight: 400 })
        .textFont({ size: 14, weight: 400 })
        .onSubmit((value: string) => {
          this.submitValue = value
        })
        .onChange((value: string) => {
          this.changeValue = value
        })
    }.padding({ top: $r('app.float.home_grid_margin'), left: $r('app.float.home_list_padding') })
  }
  /*底部Tab构造器*/
  //https://blog.csdn.net/nopyramid/article/details/135557340
  //https://blog.csdn.net/shanghai597/article/details/138790221
  /*
官方给出的样例一共有四个输入:
title:tabbar显示的文本
targetId:tabbar的唯一编号
selectedImg:激活时的图标
normalImg:去激活时的图标
*/
  @Builder TabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) {
    Column() {
      Image(this.currentIndex === index ? selectedImg : normalImg)
        .width($r('app.float.mainPage_baseTab_size'))
        .height($r('app.float.mainPage_baseTab_size'))
      Text(title)
        .margin({ top: $r('app.float.mainPage_baseTab_top') })
        .fontSize($r('app.float.main_tab_fontSize'))
        .fontColor(this.currentIndex === index ? $r('app.color.tab_selected') : $r('app.color.tab_unselected'))
    }
    .justifyContent(FlexAlign.Center)
    .height($r('app.float.mainPage_barHeight'))
    .width(CommonConstants.FULL_PARENT)
    .onClick(() => {
      this.currentIndex = index;
      this.tabController.changeIndex(this.currentIndex);
    })
  }

  resetVisibleAndLength(index : number){
    if (index === 0) {
      this.enableFlag = true;
    } else {
      this.enableFlag = false;
    }
  }

/*
https://blog.csdn.net/m0_74037076/article/details/140128539
此处搜索框没有实现点击搜索功能,可以参考此链接主要是调用Bmob.Query的where查询,用到了LIKE这个模糊查询方法。

还可以通过从数据库中请求数据进行过滤实现:
存储鸿蒙有两种方式:
1、首选项存储(适合存储少量的数据,已键值对的形式存储)
2、关系型数据存储RDB(适合大量数据存储)
https://blog.csdn.net/qq_53123067/article/details/135554427
https://blog.csdn.net/2302_79548774/article/details/140646552
*/
  build() {
    Column() {
      /*搜索框*/
      Row(){
        Search({ value: this.changeValue, placeholder: '男士羽绒服', controller: this.searchController })
          .searchButton('搜索')
          .width(CommonConstants.FULL_PARENT)
          .height(30)
          .backgroundColor('#F5F5F5')
          .placeholderColor(Color.Grey)
          .placeholderFont({ size: 14, weight: 400 })
          .textFont({ size: 14, weight: 400 })
          .onSubmit((value: string) => {
            this.submitValue = value
          })
          .onChange((value: string) => {
            this.changeValue = value
          })
      }.padding({ top: $r('app.float.home_grid_margin'), left: $r('app.float.home_list_padding') })
      .visibility(this.enableFlag ? Visibility.Visible : Visibility.None)


      /*顶部Tab*/
      Column() {
        Tabs({ barPosition: BarPosition.Start }) {
          /*推荐页*/
          TabContent() {HomePage()}.tabBar(CommonConstants.HOME_TITLE)
          /*
 WomanPage()方法实现点击女装按钮(WOMAN_TITLE)实现点击后的页面,参考2.2的代码分析
*/
          /*女装页*/
          TabContent() {WomanPage()}.tabBar(CommonConstants.WOMAN_TITLE)
          /*男装页*/
          TabContent() {ManPage()}.tabBar(CommonConstants.MAN_TITLE)
          /*运动页*/
          TabContent() {SportPage()}.tabBar(CommonConstants.SPORT_TITLE)
          /*电脑办公页*/
          TabContent() {ComputerPage()}.tabBar(CommonConstants.TEC_TITLE)
          /*其他*/
          TabContent() {}.tabBar(CommonConstants.OTHER_TITLE)
        }.barHeight('35vp')
        .vertical(false).scrollable(true).barMode(BarMode.Scrollable)
        .onChange((index: number) => {
          console.info(index.toString())
        }).width('100%').backgroundColor(0xF1F3F5)
      }.width('100%')
      .height('87%')
      .visibility(this.enableFlag ? Visibility.Visible : Visibility.None)

      /*底部Tab*/
      Column() {
        Tabs({ barPosition: BarPosition.End, controller : this.tabController}) {
          /*首页*/
          TabContent() {
            HomePage()
          }
          .padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
          .backgroundColor($r('app.color.mainPage_backgroundColor'))
          .tabBar(this.TabBuilder(CommonConstants.HOME_TITLE, CommonConstants.HOME_TAB_INDEX, $r('app.media.home_selected'), $r('app.media.home_normal')))
          /*通过 Shop()进入购物车页面,参考2.3的购物车代码*/
          /*购物车*/
          TabContent() {
            Shop()
          }
          .padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
          .tabBar(this.TabBuilder(CommonConstants.SHOP_TITLE, CommonConstants.SHOP_TAB_INDEX, $r('app.media.shopping_selected'), $r('app.media.shopping_normal')))
          /*个人中心*/
          TabContent() {
            Mine()
          }.padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
          .tabBar(this.TabBuilder(CommonConstants.USER_TITLE, CommonConstants.USER_TAB_INDEX, $r('app.media.mine_selected'), $r('app.media.mine_normal')))
        }
        .vertical(false)
        .scrollable(true)
        .barMode(BarMode.Fixed)
        .onChange((index: number) => {
          console.debug('index number: '+index.toString())
          this.resetVisibleAndLength(index)
        }).width('100%')
        .backgroundColor(0xF1F3F5)
      }
      .width('100%')
      .height(this.enableFlag ? '50vp' : '100%')
      /*-----------------------------end------------------------------------*/
    }.width('100%')
    .height(CommonConstants.FULL_PARENT)
  }

}

@Component
struct TopTabDisplay{
  enableFlag : boolean = null!;

  build(){
    Column() {
      Tabs({ barPosition: BarPosition.Start }) {
        /*推荐页*/
        TabContent() {
          HomePage()
        }.tabBar(CommonConstants.HOME_TITLE)
        /*女装页*/
        TabContent() {
          WomanPage()
        }
        .tabBar(CommonConstants.WOMAN_TITLE)
        /*男装页*/
        TabContent() {
          ManPage()
        }
        .tabBar(CommonConstants.MAN_TITLE)
        /*运动页*/
        TabContent() {
          SportPage()
        }
        .tabBar(CommonConstants.SPORT_TITLE)
        /*电脑办公页*/
        TabContent() {
          ComputerPage()
        }
        .tabBar(CommonConstants.TEC_TITLE)
        /*其他*/
        TabContent() {

        }
        .tabBar(CommonConstants.OTHER_TITLE)
      }
      .vertical(false)
      .scrollable(true)
      .barMode(BarMode.Scrollable)
      .onChange((index: number) => {
        console.info(index.toString())
      })
      .width('100%')
      .backgroundColor(0xF1F3F5)
    }
    .width('100%')
    .height('85%')
    .visibility(this.enableFlag ? Visibility.Visible : Visibility.None)
  }
}



@Component
struct BottomTabContentDisplay{
  build(){

  }
}

2.2、女装页面代码分析

在这里插入图片描述

import mainViewModel from '../../viewmodel/MainViewModel';
import ItemData from '../../viewmodel/ItemData';
import CommonConstants from '../../constants/CommonConstants';

@Component
export default struct WomanPage {
  private swiperController: SwiperController = new SwiperController();
  private tabsController: TabsController = new TabsController();

  /*装饰器 - 展示TabContent*/
  @Builder BuildTabContent(index : number, istabcontent : boolean ) {
    Grid() {
      ForEach(mainViewModel.getWomanPageData(index), (item: ItemData) => {
        GridItem() {
          Column() {
            Image(item.img)
              .width($r('app.float.small_img_5wh'))
              .height(istabcontent ? $r('app.float.small_img_8hg') : $r('app.float.small_img_3hg'))
            Text(item.title)
              .fontSize($r('app.float.little_text_size'))
              .margin({ top: $r('app.float.home_homeCell_margin') })
          }.backgroundColor(istabcontent ? null : Color.White)
        }
      }, (item: ItemData) => JSON.stringify(item))
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr')
    .columnsGap($r('app.float.home_grid_columnsGap'))
    .rowsGap($r('app.float.home_grid_columnsGap'))
    .padding({ bottom: $r('app.float.home_grid_padding') })
    .height(istabcontent ? $r('app.float.tab_250hg') : $r('app.float.tab_180hg'))
    .backgroundColor(istabcontent ? Color.White : null)
    .borderRadius($r('app.float.home_grid_borderRadius'))
  }

  /*装饰器 - 展示轮播图*/
  @Builder BuildSwiper() {
    Swiper(this.swiperController) {
      ForEach(mainViewModel.getWomanPagesSwiperImages(), (img: Resource) => {
        Image(img)
          .height('200vp')
          .width(CommonConstants.FULL_PARENT)
          .borderRadius($r('app.float.home_swiper_borderRadius'))
      }, (img: Resource) => JSON.stringify(img.id))
    }
    .margin({ top: $r('app.float.home_swiper_margin') })
    .autoPlay(false)
  }

  build() {
    Scroll() {
      Column({ space: CommonConstants.COMMON_SPACE }) {
        /*轮播图*/
        this.BuildSwiper()
        /*精选分类*/
        Tabs({ barPosition: BarPosition.Start, controller: this.tabsController }) {
          /*精选分类 tab*/
          TabContent(){
            this.BuildTabContent(0, true)
          }.tabBar(CommonConstants.Category_TITLE1)
          /*上装 tab*/
          TabContent(){
            this.BuildTabContent(1, true)
          }.tabBar(CommonConstants.Category_TITLE2)
          /*下装 tab*/
          TabContent(){
            this.BuildTabContent(2, true)
          }.tabBar(CommonConstants.Category_TITLE3)
        }.height('300vp')
        .padding({ left: $r('app.float.home_list_padding'), right: $r('app.float.home_list_padding') })
        /*块状品牌*/
        LogoDisplay()
        Blank();
        Blank();
      }
    }
  }
}

/*自定义组件-show Gird Logo Info*/
@Component
struct LogoDisplay {
  build(){
    Grid() {
      ForEach(mainViewModel.getWomanBrandData(), (item: ItemData) => {
        GridItem() {
          Column() {
            Image(item.img)
              .width($r('app.float.small_img_5wh'))
              .height($r('app.float.small_img_3hg'))
            Text(item.title)
              .fontSize($r('app.float.little_text_size'))
              .margin({ top: $r('app.float.home_homeCell_margin') })
          }
        }
        .backgroundColor(Color.White)
      }, (item: ItemData) => JSON.stringify(item))
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr')
    .columnsGap($r('app.float.home_grid_columnsGap'))
    .rowsGap($r('app.float.home_grid_rowGap'))
    .padding({
      left: $r('app.float.home_grid_padding'),
      right: $r('app.float.home_grid_padding'),
      bottom: $r('app.float.home_grid_padding')
    })
    .height($r('app.float.tab_180hg'))
    .borderRadius($r('app.float.home_grid_borderRadius'))
  }
}

getWomanBrandData()方法是数据构造方式,目前代码是写死的,可以从数据库或者首选项里面获取(固定分类少量推荐使用首选项方式),代码如下:

//数据构造代码
import { mockCardInfo } from '../datasource/MockData';
import ItemData from './ItemData';
export class MainViewModel{

  getMainPagesSwiperImages(): Array<Resource> {
    let swiperImages: Resource[] = [
    $r('app.media.sw1'),
    $r('app.media.sw2'),
    // $r('app.media.sw3')
    ];
    return swiperImages;
  }

  getWomanPagesSwiperImages(): Array<Resource> {
    let swiperImages: Resource[] = [
    $r('app.media.sw1'),
    $r('app.media.sw2'),
    ];
    return swiperImages;
  }

  getManPagesSwiperImages(): Array<Resource> {
    let swiperImages: Resource[] = [
    $r('app.media.sw1'),
    $r('app.media.sw2'),
    $r('app.media.sw3')
    ];
    return swiperImages;
  }

  getFirstGridData(): Array<ItemData> {
    let firstGridData: ItemData[] = [
      new ItemData($r('app.string.mainPage_brand'), $r('app.media.grid1'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.mainPage_found'), $r('app.media.grid2'), $r('app.string.mainPage_text_found'))
    ];
    return firstGridData;
  }

  getSecondGridData(): Array<ItemData> {
    let secondGridData: ItemData[] = [
      new ItemData($r('app.string.row1_money'), $r('app.media.row1'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row2_money'), $r('app.media.row2'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row3_money'), $r('app.media.row3'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row4_money'), $r('app.media.row4'), $r('app.string.mainPage_text_brand'))
    ];
    return secondGridData;
  }

  getListCardData(): Array<ItemData> {
    let listCardData: ItemData[] = [
      new ItemData($r('app.string.row1_money'), $r('app.media.card'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row2_money'), $r('app.media.card'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row3_money'), $r('app.media.card'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.row4_money'), $r('app.media.card'), $r('app.string.mainPage_text_brand'))
    ];
    return listCardData;
  }

  getWomanPageData(index : number): Array<ItemData> {
    let womanPageData: ItemData[] = []
    if (index == 0) {
      womanPageData = [
        new ItemData($r('app.string.woman_short_eiderdown'), $r('app.media.w_shortJacket')),
        new ItemData($r('app.string.woman_undershirt'), $r('app.media.w_undershirt')),
        new ItemData($r('app.string.woman_skirt'), $r('app.media.w_skirt')),
        new ItemData($r('app.string.woman_pants'), $r('app.media.w_pants')),
        new ItemData($r('app.string.woman_jackets'), $r('app.media.w_jackets')),
        new ItemData($r('app.string.woman_hoodies'), $r('app.media.w_hoodies')),
        new ItemData($r('app.string.woman_fur'), $r('app.media.w_fur')),
        new ItemData($r('app.string.woman_long_eiderdown'), $r('app.media.w_eiderdown')),
        new ItemData($r('app.string.woman_coat'), $r('app.media.w_coat')),
        new ItemData($r('app.string.woman_cardigan'), $r('app.media.w_cardigan')),
      ];
    } else if (index == 1) {
      womanPageData = [
        new ItemData($r('app.string.woman_short_eiderdown'), $r('app.media.w_shortJacket')),
        new ItemData($r('app.string.woman_undershirt'), $r('app.media.w_undershirt')),
        new ItemData($r('app.string.woman_skirt'), $r('app.media.w_skirt')),
        new ItemData($r('app.string.woman_cardigan'), $r('app.media.w_cardigan')),
      ];
    } else if (index == 2){
      womanPageData = [
        new ItemData($r('app.string.woman_hoodies'), $r('app.media.w_hoodies')),
        new ItemData($r('app.string.woman_fur'), $r('app.media.w_fur')),
        new ItemData($r('app.string.woman_long_eiderdown'), $r('app.media.w_eiderdown')),
        new ItemData($r('app.string.woman_coat'), $r('app.media.w_coat')),
        new ItemData($r('app.string.woman_cardigan'), $r('app.media.w_cardigan'))
      ];
    } else {
      womanPageData = [
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand1')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand2')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand3')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand4')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand5')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand6')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand7')),
        new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand8'))
      ];
    }

    return womanPageData;
  }

  getWomanTopCategoryData(): Array<ItemData> {
    let womanCategoryData: ItemData[] = [
      new ItemData($r('app.string.woman_short_eiderdown'), $r('app.media.w_shortJacket')),
      new ItemData($r('app.string.woman_undershirt'), $r('app.media.w_undershirt')),
      new ItemData($r('app.string.woman_skirt'), $r('app.media.w_skirt')),
      new ItemData($r('app.string.woman_cardigan'), $r('app.media.w_cardigan')),
    ];
    return womanCategoryData;
  }

  getWomanUnderCategoryData(): Array<ItemData> {
    let womanCategoryData: ItemData[] = [
      new ItemData($r('app.string.woman_hoodies'), $r('app.media.w_hoodies')),
      new ItemData($r('app.string.woman_fur'), $r('app.media.w_fur')),
      new ItemData($r('app.string.woman_long_eiderdown'), $r('app.media.w_eiderdown')),
      new ItemData($r('app.string.woman_coat'), $r('app.media.w_coat')),
      new ItemData($r('app.string.woman_cardigan'), $r('app.media.w_cardigan'))
    ];
    return womanCategoryData;
  }

  getWomanBrandData(): Array<ItemData> {
    let womanBrandData: ItemData[] = [
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand1')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand2')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand3')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand4')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand5')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand6')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand7')),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.brand8'))
    ];
    return womanBrandData;
  }

  getManWaterData() : Array<ItemData> {
    let manWaterData : ItemData[] = [
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man1'), mockCardInfo[0].cardId, mockCardInfo[0].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man2'), mockCardInfo[1].cardId, mockCardInfo[1].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man3'), mockCardInfo[2].cardId, mockCardInfo[2].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man4'), mockCardInfo[3].cardId, mockCardInfo[3].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man5'), mockCardInfo[4].cardId, mockCardInfo[4].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man6'), mockCardInfo[5].cardId, mockCardInfo[5].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man7'), mockCardInfo[6].cardId, mockCardInfo[6].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man8'), mockCardInfo[7].cardId, mockCardInfo[7].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man9'), mockCardInfo[8].cardId, mockCardInfo[8].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man10'), mockCardInfo[9].cardId, mockCardInfo[9].price),
      new ItemData($r('app.string.woman_text_brand'), $r('app.media.man11'), mockCardInfo[10].cardId, mockCardInfo[10].price)
    ];
    return manWaterData;
  }

/*  getSettingListData(): Array<ItemData> {
    let settingListData: ItemData[] = [
      new ItemData($r('app.string.setting_list_news'), $r('app.media.news'), $r("app.string.setting_toggle")),
      new ItemData($r('app.string.setting_list_data'), $r('app.media.data')),
      new ItemData($r('app.string.setting_list_menu'), $r('app.media.menu')),
      new ItemData($r('app.string.setting_list_about'), $r('app.media.about')),
      new ItemData($r('app.string.setting_list_storage'), $r('app.media.storage')),
      new ItemData($r('app.string.setting_list_privacy'), $r('app.media.privacy'))
    ];
    return settingListData;
  }*/

  getMimeGridData(): Array<ItemData> {
    let firstGridData: ItemData[] = [
      new ItemData($r('app.string.mime_pay'), $r('app.media.pay'), $r('app.string.mainPage_text_brand')),
      new ItemData($r('app.string.mine_car'), $r('app.media.car'), $r('app.string.mainPage_text_found')),
      new ItemData($r('app.string.mime_talk'), $r('app.media.talk'), $r('app.string.mainPage_text_found'))
    ];
    return firstGridData;
  }

  getMimeGridSecondData(): Array<ItemData> {
    let secondGridData: ItemData[] = [
      new ItemData($r('app.string.mine_coupon'), $r('app.media.m_coupon_center')),
      new ItemData($r('app.string.mine_message'), $r('app.media.m_message_center')),
      new ItemData($r('app.string.mine_sub'), $r('app.media.love')),
      new ItemData($r('app.string.mine_shop'), $r('app.media.shopping')),
      new ItemData($r('app.string.mine_vip'), $r('app.media.m_vip_center')),
      new ItemData($r('app.string.mine_account'), $r('app.media.m_account_center')),
      new ItemData($r('app.string.mine_note'), $r('app.media.about'))


    ];
    return secondGridData;
  }


}

export default new MainViewModel();

2.3、购物车页面代码分析

import CommonConstants from '../constants/CommonConstants'
import { getShopCardInfo } from '../datasource/DataUtils';
import { CardInfo } from '../viewmodel/DataModels';

@Component
export default struct Shop {
//getShopCardInfo()构造购物车列表参考DataUtils和MockData两个代码类
  private shopCardInfo: Array<CardInfo> = getShopCardInfo();
  @State shopNums : number = 0;
  @State allMoney : number = 0;

  addShopCardInfo(price : number, size : number){
    this.allMoney = this.allMoney + price ;
    this.shopNums = this.shopNums + size;
  }

  deleteShopCardInfo(price : number, size : number){
    this.allMoney = this.allMoney - price;
    this.shopNums = this.shopNums - size;
  }

  build(){
    Scroll() {
      Column({ space: CommonConstants.COMMON_SPACE }) {
        /*购物车*/
        Column() {
          Text($r('app.string.shopping_cart'))
            .fontWeight(FontWeight.Medium)
            .fontSize($r('app.float.page_title_text_size'))
            .margin({ top: $r('app.float.mainPage_tabTitles_margin') })
            .padding({ left: $r('app.float.mainPage_tabTitles_padding') })
        }
        .width(CommonConstants.FULL_PARENT)
        .alignItems(HorizontalAlign.Start)

        List({ space: 20, initialIndex: 0 }) {
          ForEach(this.shopCardInfo, (cardInfo: CardInfo) => {
            ListItem() {
              Flex({ direction: FlexDirection.Row  }) {//行布局
                Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
                  .selectedColor('#007DFF')
                  .borderRadius($r('app.float.home_swiper_borderRadius'))
                  .onChange((value: boolean) => {
                    console.info('Checkbox1 change is' + value)
                    if (value) {
                      this.addShopCardInfo(cardInfo.price, cardInfo.numb);
                    } else {
                      this.deleteShopCardInfo(cardInfo.price, cardInfo.numb);
                    }
                  })
                Image(cardInfo.image)
                  .objectFit(ImageFit.Cover)
                  .width('70vp')
                  .borderRadius($r('app.float.home_swiper_borderRadius'))
                Flex({ direction: FlexDirection.Column  }) {
                  Text(cardInfo.desc)
                    .fontSize('15')
                    .width('200vp')
                  Select([{ value: cardInfo.proper+':'+cardInfo.size },
                    { value: 'bbb'},
                    { value: 'ccc'},
                    { value: 'ddd'}])//打开商品详情页
                    .selected(2)
                    .value(cardInfo.proper+':'+cardInfo.size)
                    .font({ size: 12, weight: 500 })
                    .fontColor('#182431')
                    .selectedOptionFont({ size: 12, weight: 400 })
                    .optionFont({ size: 12, weight: 400 })

                  Text('¥' +cardInfo.price)
                    .fontSize('15')
                    .fontColor(Color.Red)

                  Text('X' +cardInfo.numb)
                    .fontSize('12').padding({left:'80%'})
                }.margin({left:'15vp'})

              }
            }.backgroundColor(Color.White)
            .borderRadius($r('app.float.setting_account_borderRadius'))
          }, (cardInfo: CardInfo) => JSON.stringify(cardInfo))
        }
        .listDirection(Axis.Vertical) // 排列方向
        .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
        .edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果
        .padding({
          top: $r('app.float.home_list_padding'),
          left: $r('app.float.home_list_padding'),
          right: $r('app.float.home_list_padding')
        })
        .width(CommonConstants.FULL_PARENT)
        .height('70%')

        /*结算*/
        Row(){
          Text('已选' + this.shopNums)

          Text('总计:¥' + this.allMoney).fontColor(Color.Red).padding({left:'20vp'})

          Button(('结算'), { type: ButtonType.Capsule })
            .width('40%')
            .height($r('app.float.login_button_height')).fontSize($r('app.float.normal_text_size')).fontColor($r('app.color.red')).fontWeight(FontWeight.Medium)
            .backgroundColor($r('app.color.grey'))
            //参考2.4代码,目前只实现弹窗页面,没有实现真正结算逻辑
            .onClick(()=>{
              AlertDialog.show({
                title: "购物车结算弹窗",
                message: "您一共买了"+this.shopNums+"件商品,总价值:"+this.allMoney+"元。",
                confirm: { value: "", action: () => {}, }
              })
            })
        }

      }
    }
  }
}

DataUtils类代码:


import router from '@ohos.router'
import { CardInfo,ProperColorData, SimpleCardInfo} from '../viewmodel/DataModels'
import { mockCardInfo, mockProperColorData, mockProperSizeData, mockShopCardInfo, mockSportCardInfo, mockTecCardInfo } from './MockData'

const DEBUG_PREVIEW = false

export function getCardInfo(cardId : string): CardInfo {
  console.log("getCardInfo:"+cardId);
  // return mockCardInfo.find(cardData => cardData.cardId === cardId);
  return new CardInfo(0,"","");
}

export function getProperColorData(): Array<ProperColorData> {
  return mockProperColorData;

}

export function getProperSizeData(): Array<number> {
  return mockProperSizeData;
}

export function getSportCardInfo(): Array<SimpleCardInfo> {
  return mockSportCardInfo;
}

export function getTecCardInfo(): Array<SimpleCardInfo> {
  return mockTecCardInfo;
}

export function getShopCardInfo(): Array<CardInfo> {
  return mockShopCardInfo;
}

MockData类代码:

import { CardInfo, ProperColorData, SimpleCardInfo } from '../viewmodel/DataModels'

export let cardInfo1: CardInfo = new CardInfo(0, '5bdbe6b0-c34a-4c35-8c8f-19be0ef8104b', $r('app.string.woman_text_brand'), $r('app.media.man1'))
cardInfo1.price = 134
cardInfo1.desc = '[2024新款]秋冬男士牛仔裤男宽松直筒弹力休闲长裤子男装'
cardInfo1.proper = '黑色'
cardInfo1.size = '均码'
cardInfo1.numb = 1;

export let cardInfo2: CardInfo = new CardInfo(1, 'c8761280-4d67-4783-ab69-1c176b75fde0', $r('app.string.woman_text_brand'), $r('app.media.man2'))
cardInfo2.price = 124
cardInfo2.desc = '[2024新款]秋冬男士卫衣男宽松弹力休闲男装'
cardInfo2.proper = '黑色'
cardInfo2.size = '均码';

cardInfo2.numb = 1;


export let cardInfo3: CardInfo = new CardInfo(2, '72464fc9-9448-43f3-9caf-2a3a6a2a07ed', $r('app.string.woman_text_brand'), $r('app.media.man3'))
cardInfo3.price = 999
cardInfo3.desc = '[2024新款]秋冬男士短袖男宽松弹力休闲男装'
cardInfo3.proper = '黑色'
cardInfo3.size = '均码'
cardInfo3.numb = 1;


export let cardInfo4: CardInfo = new CardInfo(3, '58fb40d9-4e36-4ff1-a1b8-7544b0334395', $r('app.string.woman_text_brand'), $r('app.media.man4'))
cardInfo4.price = 78
cardInfo4.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo5: CardInfo = new CardInfo(4, '9c4b64d4-62c8-48e4-b685-97e8e5f50b21', $r('app.string.woman_text_brand'), $r('app.media.man5'))
cardInfo5.price = 123
cardInfo5.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo6: CardInfo = new CardInfo(5, '5b4d9098-0011-4383-9d5c-91f67ddfd83c', $r('app.string.woman_text_brand'), $r('app.media.man6'))
cardInfo6.price = 453
cardInfo6.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo7: CardInfo = new CardInfo(6, '7b6fa990-e114-4361-a9ff-00d5a93bed07', $r('app.string.woman_text_brand'), $r('app.media.man7'))
cardInfo7.price = 765
cardInfo7.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo8: CardInfo = new CardInfo(7, '8794cff1-094a-4b6d-8d04-d6238b806e77', $r('app.string.woman_text_brand'), $r('app.media.man8'))
cardInfo8.price = 66
cardInfo8.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo9: CardInfo = new CardInfo(8, '8531161a-a2f9-4c06-8c94-18fd7bb16078', $r('app.string.woman_text_brand'), $r('app.media.man9'))
cardInfo9.price = 88
cardInfo9.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo10: CardInfo = new CardInfo(9, '26b2a836-b826-4cb3-b247-119873ef4076', $r('app.string.woman_text_brand'), $r('app.media.man10'))
cardInfo10.price = 73
cardInfo10.desc = '[2024新款]秋冬男士羽绒服男修身男装'

export let cardInfo11: CardInfo = new CardInfo(10, '34f7f253-d136-4b88-87d7-724b5ec4d23c', $r('app.string.woman_text_brand'), $r('app.media.man11'))
cardInfo11.price = 90
cardInfo11.desc = '[2024新款]秋冬男士羽绒服男修身男装'

/*模拟瀑布流数据*/
export let mockCardInfo: Array<CardInfo> = [
  cardInfo1,cardInfo2,cardInfo3,cardInfo4,cardInfo5,cardInfo6,cardInfo7,cardInfo8,cardInfo9,cardInfo10,cardInfo11
]

export let properInfo1: ProperColorData = new ProperColorData(0, '', '烟黑', $r('app.media.man11'))
export let properInfo2: ProperColorData = new ProperColorData(1, '', '线灰', $r('app.media.man11'))
export let properInfo3: ProperColorData = new ProperColorData(2, '', '蓝色', $r('app.media.man11'))
export let properInfo4: ProperColorData = new ProperColorData(3, '', '深蓝', $r('app.media.man11'))
export let properInfo5: ProperColorData = new ProperColorData(4, '', '深灰', $r('app.media.man11'))

/*模拟商品颜色种类*/
export let mockProperColorData : Array<ProperColorData> = [
  properInfo1,properInfo2,properInfo3,properInfo4,properInfo5
]
/*模拟商品参数*/
export let mockProperSizeData : Array<number> = [
  28,29,30,31,32,33,34,36,38
]

export let sportCardInfo1: SimpleCardInfo = new SimpleCardInfo(0, '1', $r('app.media.s1'))
export let sportCardInfo2: SimpleCardInfo = new SimpleCardInfo(1, '2', $r('app.media.s2'))
export let sportCardInfo3: SimpleCardInfo = new SimpleCardInfo(2, '3', $r('app.media.s3'))
export let sportCardInfo4: SimpleCardInfo = new SimpleCardInfo(3, '4', $r('app.media.s4'))
/*模拟运动的数据*/
export let mockSportCardInfo : Array<SimpleCardInfo> = [
  sportCardInfo1, sportCardInfo2, sportCardInfo3, sportCardInfo4
]

export let tecCardInfo1: SimpleCardInfo = new SimpleCardInfo(0, '1', $r('app.media.tec1'))
export let tecCardInfo2: SimpleCardInfo = new SimpleCardInfo(1, '2', $r('app.media.tec2'))
export let tecCardInfo3: SimpleCardInfo = new SimpleCardInfo(2, '3', $r('app.media.tec3'))
export let tecCardInfo4: SimpleCardInfo = new SimpleCardInfo(3, '4', $r('app.media.tec4'))
export let tecCardInfo5: SimpleCardInfo = new SimpleCardInfo(4, '4', $r('app.media.tec5'))
/*模拟电脑、IT数据*/
export let mockTecCardInfo : Array<SimpleCardInfo> = [
  tecCardInfo1, tecCardInfo2, tecCardInfo3, tecCardInfo4, tecCardInfo5
]

/*模拟购物车数据*/
export let mockShopCardInfo: Array<CardInfo> = [
  cardInfo1,cardInfo2,cardInfo3
]

2.4、购物车结算代码

在这里插入图片描述
这个可以实现对接微信/支付宝/银联等实现付款的代码。

3、个人中心代码分析

在这里插入图片描述


import CommonConstants from '../constants/CommonConstants';
import ItemData from '../viewmodel/ItemData';
import mainViewModel from '../viewmodel/MainViewModel';


@Component
export default struct Mine {

  build() {
    Scroll() {
      /*个人资料*/
      Column({ space: CommonConstants.COMMON_SPACE }) {
        Row() {
          Image($r('app.media.account'))
            .width($r('app.float.setting_account_size'))
            .height($r('app.float.setting_account_size'))
          Column() {
            Text($r('app.string.setting_account_name'))
              .fontSize($r('app.float.setting_account_fontSize'))
            Text($r('app.string.setting_account_email'))
              .fontSize($r('app.float.little_text_size'))
              .margin({ top: $r('app.float.setting_name_margin') })
          }
          .alignItems(HorizontalAlign.Start)
          .margin({ left: $r('app.float.setting_account_margin') })
        }
        .margin({ top: $r('app.float.setting_list_height')})
        .alignItems(VerticalAlign.Center)
        .width('100%')
        .height($r('app.float.setting_account_height'))
        .backgroundColor(Color.White)
        .padding({left: $r('app.float.setting_account_padding'), right: $r('app.float.setting_account_padding') })
        .borderRadius($r('app.float.setting_account_borderRadius'))
        /*我的订单*/
        Flex({ direction: FlexDirection.Column }) {
          Row(){
            Text(CommonConstants.MY_ORDERS)
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .padding({left: $r('app.float.home_grid_padding'),top:$r('app.float.home_grid_padding')})
          }

          Grid() {
            ForEach(mainViewModel.getMimeGridData(), (item: ItemData) => {
              GridItem() {
                Column() {
                  Image(item.img).objectFit(ImageFit.Contain).height($r('app.float.setting_list_height')).width($r('app.float.setting_list_height'))
                  Text(item.title).fontSize($r('app.float.little_text_size')).margin({ top: $r('app.float.home_homeCell_margin') })
                }
              }
            }, (item: ItemData ) => JSON.stringify(item))
          }
          .columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr').columnsGap($r('app.float.home_grid_columnsGap')).rowsGap($r('app.float.home_grid_rowGap'))
          .height($r('app.float.home_firstGrid_height')).width('100%')
        }
        .width('100%').height('130vp').margin({ left: $r('app.float.home_grid_padding'), right: $r('app.float.home_grid_padding') }).borderRadius($r('app.float.home_grid_borderRadius'))
        .backgroundColor(Color.White)
        /*功能区*/
        Grid() {
          ForEach(mainViewModel.getMimeGridSecondData(), (item: ItemData) => {
            GridItem() {
              Column() {
                Image(item.img).objectFit(ImageFit.Contain).height($r('app.float.setting_account_text_height')).width($r('app.float.setting_account_text_height'))
                Text(item.title).fontSize($r('app.float.little_text_size')).margin({ top: $r('app.float.home_homeCell_margin') })
              }
            }
          }, (item: ItemData) => JSON.stringify(item))
        }
        .columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr 1fr').columnsGap($r('app.float.home_grid_columnsGap')).rowsGap($r('app.float.home_grid_rowGap'))
        .margin({left: $r('app.float.home_grid_padding'), right: $r('app.float.home_grid_padding')})
        .height('150vp').width('100%').backgroundColor(Color.White).borderRadius($r('app.float.home_grid_borderRadius'))
        /*分割*/
        Blank()
        /*退出按钮*/
        Button($r('app.string.setting_button'), { type: ButtonType.Capsule })
          .width(CommonConstants.BUTTON_WIDTH)
          .height($r('app.float.login_button_height')).fontSize($r('app.float.normal_text_size')).fontColor($r('app.color.red')).fontWeight(FontWeight.Medium)
          .backgroundColor($r('app.color.grey')).margin({ bottom: $r('app.float.setting_button_bottom')})
      }
      .height(CommonConstants.FULL_PARENT)

    }
  }
}

目前此代码只实现展示功能,具体的业务逻辑上还没有实现。