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)
}
}
}
目前此代码只实现展示功能,具体的业务逻辑上还没有实现。