天天看點

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

本文會通過ETS實作一個購物車應用

1. 建立商品清單頁面

在這一節,我們将完成首頁界面以及商品清單頁簽的設計,效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

從上面效果圖可以看出,主界面商品清單頁簽主要由下面三個部分組成:

(1)頂部的Tabs元件。

(2)中間TabContent元件内包含List元件。其中List元件的item是一個水準布局,由一個垂直布局和一個Image元件組成;item中的垂直布局由3個Text元件組成。

(3)底部的頁簽導航。

下面來一起建立第一個頁面,第一個頁面的檔案是pages/HomePage.ets,現在先建立該檔案。

 在與pages檔案夾同級目錄建立一個model檔案夾,并在model目錄下建立ArsData.ets、GoodsData.ets、Menu.ets和GoodsDataModels.ets檔案,其中ArsData.ets、GoodsData.ets、Menu.ets是資料實體類,GoodsDataModels.ets是存放這三種實體資料集合,并定義了擷取各種資料集合的方法。資料實體包含實體的屬性和構造方法,可通過new ArsData(string,string) 來擷取ArsData對象,ArsData.ets内容如下:

let NextId = 0; 
export class ArsData { 
  id: string; 
  title: string; 
  content: string; 
 
  constructor(title: string, content: string) { 
    this.id = `${NextId++}`; 
    this.title = title; 
    this.content = content; 
  } 
}      

GoodsData.ets代碼如下:

let NextId = 0; 
export class GoodsData { 
  id: string; 
  title: string; 
  content: string; 
  price: number; 
  imgSrc: Resource; 
 
  constructor(title: string, content: string, price: number, imgSrc: Resource) { 
    this.id = `${NextId++}`; 
    this.title = title; 
    this.content = content; 
    this.price = price; 
    this.imgSrc = imgSrc; 
  } 
}      

一個檔案中可以包含多個class ,Menu.ets中就包含了Menu類和ImageItem類,Menu.ets代碼如下:

let NextId = 0; 
export class Menu { 
  id: string; 
  title: string; 
  num: number; 
 
  constructor(title: string, num: number) { 
    this.id = `${NextId++}`; 
    this.title = title; 
    this.num = num; 
  } 
} 
 
export class ImageItem { 
  id: string; 
  title: string; 
  imageSrc: Resource; 
 
  constructor(title: string, imageSrc: Resource) { 
    this.id = `${NextId++}`; 
    this.title = title; 
    this.imageSrc = imageSrc; 
  } 
} 
GoodsDataModels.ets代碼如下:
import {GoodsData} from './GoodsData' 
 
import {Menu, ImageItem} from './Menu' 
import {ArsData} from './ArsData' 
// 擷取商品清單資料 
export function initializeOnStartup(): Array<GoodsData> { 
  let GoodsDataArray: Array<GoodsData> = [] 
  GoodsComposition.forEach(item => { 
    console.log(item.title); 
    GoodsDataArray.push(new GoodsData(item.title, item.content, item.price, item.imgSrc)); 
  }) 
  return GoodsDataArray; 
} 
// 擷取底部預設圖檔清單資料 
export function getIconPath(): Array<string> { 
  let IconPath: Array<string> = ['nav/icon-buy.png','nav/icon-shopping-cart.png','nav/icon-my.png'] 
 
  return IconPath; 
} 
// 擷取選中後圖檔清單資料 
export function getIconPathSelect(): Array<string> { 
  let IconPathSelect: Array<string> = ['nav/icon-home.png','nav/icon-shopping-cart-select.png','nav/icon-my-select.png'] 
 
  return IconPathSelect; 
} 
// 擷取商品詳情頁圖檔詳情清單 
export function getDetailImages(): Array<string> { 
  let detailImages: Array<string> = ['computer/computer1.png','computer/computer2.png','computer/computer3.png','computer/computer4.png','computer/computer5.png','computer/computer6.png'] 
 
  return detailImages; 
} 
 
// 擷取菜單資料清單 
export function getMenu(): Array<Menu> { 
  let MenuArray: Array<Menu> = [] 
  MyMenu.forEach(item => { 
    MenuArray.push(new Menu(item.title,item.num)); 
  }) 
  return MenuArray; 
} 
// 擷取MyTrans資料清單 
export function getTrans(): Array<ImageItem> { 
  let ImageItemArray: Array<ImageItem> = [] 
  MyTrans.forEach(item => { 
    ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); 
  }) 
  return ImageItemArray; 
} 
// 擷取More資料清單 
export function getMore(): Array<ImageItem> { 
  let ImageItemArray: Array<ImageItem> = [] 
  MyMore.forEach(item => { 
    ImageItemArray.push(new ImageItem(item.title,item.imageSrc)); 
  }) 
  return ImageItemArray; 
} 
// 擷取參數清單 
export function getArs(): Array<ArsData> { 
  let ArsItemArray: Array<ArsData> = [] 
  ArsList.forEach(item => { 
    ArsItemArray.push(new ArsData(item.title,item.content)); 
  }) 
  return ArsItemArray; 
}      

在HomePage.ets檔案中建立商品清單頁簽相關的元件,其中GoodsHome效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct GoodsHome { 
  private goodsItems: GoodsData[] 
  build() { 
    Column() { 
      Tabs() { 
        TabContent() { 
          GoodsList({ goodsItems: this.goodsItems }); 
        } 
        .tabBar("Top Sellers") 
        .backgroundColor(Color.White) 
        TabContent() { 
          GoodsList({ goodsItems: this.goodsItems }); 
        } 
        .tabBar("Recommended") 
        .backgroundColor(Color.White) 
        TabContent() { 
          GoodsList({ goodsItems: this.goodsItems }); 
        } 
        .tabBar("Lifestyle") 
        .backgroundColor(Color.White) 
        TabContent() { 
          GoodsList({ goodsItems: this.goodsItems }); 
        } 
        .tabBar("Deals") 
        .backgroundColor(Color.White) 
      } 
      .barWidth(500) 
      .barHeight(25) 
      .scrollable(true) 
      .barMode(BarMode.Scrollable) 
      .backgroundColor('#007DFF') 
      .height(630) 
 
    } 
    .alignItems(HorizontalAlign.Start) 
    .width('100%') 
  } 
}      

在GoodsHome中使用Tabs元件,在Tabs元件中設定4個TabContent,給每個TabContent設定tabBar屬性,并設定TabContent容器中的内容GoodsList元件,GoodsList元件的代碼如下:

@Component 
struct GoodsList { 
  private goodsItems: GoodsData[] 
  build() { 
    Column() { 
      List() { 
        ForEach(this.goodsItems, item => { 
          ListItem() { 
            GoodsListItem({ goodsItem: item }) 
          } 
        }, item => item.id.toString()) 
      } 
      .height('100%') 
      .width('100%') 
      .align(Alignment.Top) 
      .margin({top: 5}) 
    } 
  } 
}      

2. 建立購物車頁面

購物車主界面如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

從上面效果圖可以看出,主界面購物車頁簽主要由下面三部分組成:

(1)頂部的Text元件。

(2)中間的List元件,其中List元件的item是一個水準的布局内包含一個toggle元件,一個Image元件和一個垂直布局,其item中的垂直布局是由2個Text元件組成。

(3)底部一個水準布局包含兩個Text元件。

import {GoodsData} from '../model/GoodsData' 
import {initializeOnStartup} from '../model/GoodsDataModels' 
import prompt from '@system.prompt'; 
 
@Entry 
@Component 
export struct ShoppingCart { 
  @Provide totalPrice : number =0 
  private goodsItems: GoodsData[] = initializeOnStartup() 
  build() { 
    Column() { 
      Column() { 
        Text('ShoppingCart') 
          .fontColor(Color.Black) 
          .fontSize(25) 
          .margin({ left: 60,right:60 }) 
          .align(Alignment.Center) 
      } 
      .backgroundColor('#FF00BFFF') 
      .width('100%') 
      .height(30) 
 
      ShopCartList({ goodsItems: this.goodsItems }); 
      ShopCartBottom() 
    } 
    .alignItems(HorizontalAlign.Start) 
 } 
}      

建立ShopCartList元件用于存放購物車商品清單,ShopCartList元件的代碼如下:

@Component 
struct ShopCartList { 
  private goodsItems: GoodsData[] 
  build() { 
    Column() { 
      List() { 
        ForEach(this.goodsItems, item => { 
          ListItem() { 
            ShopCartListItem({ goodsItem: item }) 
          } 
        }, item => item.id.toString()) 
      } 
      .height('100%') 
      .width('100%') 
      .align(Alignment.Top) 
      .margin({top: 5}) 
    } 
    .height(570) 
  } 
}      

ShopCartListItem元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct ShopCartListItem { 
  @Consume totalPrice: number 
  private goodsItem: GoodsData 
  build() { 
      Row() { 
          Toggle({type: ToggleType.Checkbox}) 
            .width(10) 
            .height(10) 
            .onChange((isOn:boolean) => { 
              if(isOn){ 
                this.totalPrice +=parseInt(this.goodsItem.price+'',0) 
              }else{ 
                this.totalPrice -= parseInt(this.goodsItem.price+'',0) 
              } 
             }) 
          Image(this.goodsItem.imgSrc) 
            .objectFit(ImageFit.ScaleDown) 
            .height(100) 
            .width(100) 
            .renderMode(ImageRenderMode.Original) 
          Column() { 
            Text(this.goodsItem.title) 
              .fontSize(14) 
            Text('¥' + this.goodsItem.price) 
              .fontSize(14) 
              .fontColor(Color.Red) 
          } 
        } 
        .height(100) 
        .width(180) 
        .margin({left: 20}) 
        .alignItems(VerticalAlign.Center) 
        .backgroundColor(Color.White) 
  } 
}      

建立ShopCartBottom元件,ShopCartBottom元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作
@Component 
struct ShopCartBottom { 
  @Consume totalPrice: number 
  build() { 
    Row() { 
      Text('Total:  ¥'+this.totalPrice) 
         .fontColor(Color.Red) 
         .fontSize(18)
 
          .margin({left:20}) 
          .width(150) 
      Text('Check Out') 
        .fontColor(Color.Black) 
        .fontSize(18) 
        .margin({right:20,left:100}) 
        .onClick(()=>{ 
        prompt.showToast({ 
          message: 'Checking Out', 
          duration: 10, 
          bottom:100 
        }) 
        }) 
    } 
    .height(30) 
    .width('100%') 
    .backgroundColor('#FF7FFFD4') 
    .alignItems(VerticalAlign.Bottom) 
  } 
}      

3. 建構商品詳情頁

商品詳情頁的效果如下圖所示:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

從上面效果圖可以看出,商品詳情頁面主要由下面五部分組成:

(1)頂部的傳回欄。

(2)Swiper元件。

(3)中間多個Text元件組成的布局。

(4)參數清單。

(5)底部的Buy。

在本節中,把上面每一部分都封裝成一個元件,然後再放到入口元件内,當點選頂部傳回圖示時傳回到首頁面的商品清單頁簽,點選底部Buy時,會觸發進度條彈窗

1.      在pages目錄下面建立一個eTS Page, 命名為ShoppingDetail.ets,config.json檔案pages屬性中也會自動添加"pages/ShoppingDetail"頁面路由。

2.      在ShoppingDetail.ets檔案中建立入口元件,元件内容如下:

@Entry 
@Component 
struct ShoppingDetail { 
  private arsItems: ArsData[] =  getArs() 
  private detailImages: string[] = getDetailImages() 
  build() { 
      Column() { 
        DetailTop() 
          Scroll() { 
            Column() { 
              SwiperTop() 
              DetailText() 
              DetailArsList({ arsItems: this.arsItems }) 
              Image($rawfile('computer/computer1.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
              Image($rawfile('computer/computer2.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
              Image($rawfile('computer/computer3.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
              Image($rawfile('computer/computer4.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
              Image($rawfile('computer/computer5.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
              Image($rawfile('computer/computer6.png')) 
                .height(220) 
                .width('100%') 
                .margin({top:30}) 
            } 
            .width('100%') 
            .flexGrow(1) 
          } 
          .scrollable(ScrollDirection.Vertical) 
          DetailBottom() 
        } 
        .height(630) 
  } 
}      

其中頂部DetailTop元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct DetailTop{ 
  build(){ 
    Column(){ 
      Row(){ 
        Image($rawfile('detail/icon-return.png')) 
          .height(20) 
          .width(20) 
          .margin({ left: 20, right: 250 }) 
          .onClick(() => { 
              router.push({ 
                uri: "pages/HomePage" 
              }) 
        }) 
      } 
      .width('100%') 
      .height(25) 
      .backgroundColor('#FF87CEEB') 
    } 
    .width('100%') 
    .height(30) 
  } 
}      

SwiperTop元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct SwiperTop{ 
  build() { 
      Column() { 
        Swiper() { 
          Image($rawfile('computer/computer1.png')) 
            .height(220) 
            .width('100%') 
          Image($rawfile('computer/computer2.png')) 
            .height(220) 
            .width('100%') 
          Image($rawfile('computer/computer3.png')) 
            .height(220) 
            .width('100%') 
          Image($rawfile('computer/computer4.png')) 
            .height(220) 
            .width('100%') 
          Image($rawfile('computer/computer5.png')) 
            .height(220) 
            .width('100%') 
          Image($rawfile('computer/computer6.png')) 
            .height(220) 
            .width('100%') 
        } 
        .index(0) 
        .autoPlay(true) 
        .interval(3000) 
        .indicator(true) 
        .loop(true) 
        .height(250) 
        .width('100%') 
      } 
      .height(250) 
      .width('100%') 
  } 
}      

DetailText元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct DetailText{ 
  build() { 
    Column() { 
      Row(){ 
        Image($rawfile('computer/icon-promotion.png')) 
        .height(30) 
        .width(30) 
        .margin({left:10}) 
        Text('Special Offer: ¥9999') 
        .fontColor(Color.White) 
        .fontSize(20) 
        .margin({left:10}) 
 
      } 
      .width('100%') 
      .height(35) 
      .backgroundColor(Color.Red) 
      Column(){ 
        Text('New Arrival: HUAWEI MateBook X Pro 2021') 
        .fontSize(15) 
        .margin({left:10}) 
        .alignSelf(ItemAlign.Start) 
        Text('13.9-Inch, 11th Gen Intel® Core™ i7, 16 GB of Memory, 512 GB of Storage, Ultra-slim Business Laptop, 3K FullView Display, Multi-screen Collaboration, Emerald Green') 
        .fontSize(10) 
        .margin({left:10}) 
        Row(){ 
          Image($rawfile('nav/icon-buy.png')) 
            .height(15) 
            .width(15) 
            .margin({left:10}) 
          Text('Limited offer') 
            .fontSize(10) 
            .fontColor(Color.Red) 
            .margin({left:100}) 
 
        } 
        .backgroundColor(Color.Pink) 
        .width('100%') 
        .height(25) 
        .margin({top:10}) 
        Text(' Shipment:         2-day shipping') 
          .fontSize(13) 
          .fontColor(Color.Red) 
          .margin({left:10,top:5}) 
          .alignSelf(ItemAlign.Start) 
        Text('    Ship To:         Hubei,Wuhan,China') 
          .fontSize(13) 
          .fontColor(Color.Red) 
          .margin({left:10,top:5}) 
          .alignSelf(ItemAlign.Start) 
          .onClick(()=>{ 
            prompt.showDialog({title:'Location Select',}) 
          TextPicker() 
 
          }) 
        Text('Guarantee:         Genuine guaranteed') 
          .fontSize(13) 
          .margin({left:10,top:5}) 
          .alignSelf(ItemAlign.Start) 
      } 
      .height(150) 
      .width('100%') 
    } 
    .height(160) 
    .width('100%') 
  } 
}      

DetailArsList元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct DetailArsList{ 
  private arsItems: ArsData[] 
  build() { 
    Scroll() { 
      Column() { 
        List() { 
          ForEach(this.arsItems, item => { 
            ListItem() { 
              ArsListItem({ arsItem: item }) 
            } 
          }, item => item.id.toString()) 
        } 
        .height('100%') 
        .width('100%') 
        .margin({ top: 5 }) 
        .listDirection(Axis.Vertical) 
      } 
      .height(200) 
    } 
  } 
}      

ArsListItem元件代碼如下:

@Component 
struct ArsListItem { 
  private arsItem: ArsData 
 
  build() { 
    Row() { 
 
      Text(this.arsItem.title+" :") 
        .fontSize(11) 
        .margin({left:20}) 
      Blank(20) 
      Text( this.arsItem.content) 
        .fontSize(11) 
        .margin({left:40,right:20}) 
    } 
    .height(14) 
    .width('100%') 
    .backgroundColor(Color.White) 
  } 
}      

DetailBottom元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@Component 
struct DetailBottom{ 
  @Provide 
  private value : number=1 
  dialogController : CustomDialogController = new CustomDialogController({ 
    builder: DialogExample({action: this.onAccept}), 
    cancel: this.existApp, 
    autoCancel: true 
  }); 
 
  onAccept() { 
 
  } 
  existApp() { 
 
  } 
  build(){ 
    Column(){ 
      Text('Buy') 
      .width(40) 
      .height(25) 
      .fontSize(20) 
      .fontColor(Color.White) 
      .onClick(()=>{ 
        this.value=1 
        this.dialogController.open() 
      }) 
    } 
    .alignItems(HorizontalAlign.Center) 
    .backgroundColor(Color.Red) 
    .width('100%') 
    .height(40) 
  } 
}      

DialogExample自定義彈窗元件效果圖如下:

#DAYU200體驗官# 基于OpenHarmony3.1的購物車應用的實作

代碼如下:

@CustomDialog 
@Component 
struct DialogExample { 
  @Consume 
  private value : number 
  controller: CustomDialogController; 
  action: () => void; 
  build() { 
    Column() { 
      Progress({value: this.value++ >=100?100:this.value, total: 100, style: ProgressStyle.Capsule}) 
        .height(50) 
        .width(100) 
        .margin({top:5}) 
    } 
    .height(60) 
    .width(100) 
  } 
}      

​​想了解更多關于開源的内容,請通路:​​

繼續閱讀