『江鸟中原』鸿蒙开发-购物车模拟应用
  YndFXHXIcSpZ 2023年12月08日 25 0

简介

大家好,我是来自中原工学院鸿蒙课程的学生。这里分享的是我自己的鸿蒙期末考查大作业-,通过一学期课程的学习,研究出来的一些成果,本文内容实现页面基本的布局以及一部分相关业务逻辑。自我感觉代码还有待改进,望多多包涵。

环境配置

软件要求

  DevEco Studio版本:DevEco Studio 3.1 Release。

  HarmonyOS SDK版本:API version 9

涉及的代码结构

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业

及文件

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_02

应用启动页:

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业_03

登录页面

展示效果图:以下分别是登录、注册、忘记密码时的页面

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_04


『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_05

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_06


相关代码展示:

//注册
@Component
export struct Login {
  @State account: string = ''
  @State password: string = ''
  build() {
    Row() {
      Column({ space: 20 }) {
        Text('欢迎').fontColor(Color.Orange).fontSize(40)

        TextInput({ placeholder: "请输入用户名" })
          .placeholderColor(Color.White)
          .width(250)
          .border({
            color:Color.White,
            radius:30,
            width:1,
            style:BorderStyle.Solid
          })
          .height(60)
          .onChange(value => {
            this.account = value
          })

        TextInput({ placeholder: "请输入密码" })
          .placeholderColor(Color.White)
          .fontColor(Color.White)
          .type(InputType.Password)
          .border({
            color:Color.White,
            radius:30,
            width:1,
            style:BorderStyle.Solid
          })
          .width(250)
          .height(60)
          .onChange(value => {
            this.password =value
          })
        Button("登录")
          .fontColor(Color.White)
          .backgroundColor(Color.Orange)
          .width(250)
          .height(40)
          .type(ButtonType.Capsule).onClick(() => {
          router.pushUrl({
            url: 'pages/HomePage',
            params: {

              account:this.account,
              password:this.password

            }
          })
        })
        Row(){
          Text('忘记密码')
            .fontColor(Color.White).onClick(()=>{
            router.pushUrl({
              url: 'pages/ResetPassword'
            })
          })

          Text("|").fontColor(Color.White).margin(30)
          Text('立即注册')
            .fontColor(Color.White)
            .onClick(()=>{
              router.pushUrl({
                url: 'pages/Register'
              })
            })
        }

      }
      .width('100%')
    }
    .height('100%')
    .linearGradient(
      {
        angle:110,
        colors:[['#ff1661be',0,1],['#ff2ed6bd',0.8],['#ff12bf74',0.1]]
      }
    )
  }
}
//注册
@Component
export struct register{
  @State account: string = ''
  @State password: string = ''
  @State password2: string = ''
  build(){
    Column(){
      Row() {
        Column({ space: 20 }) {
          Text('注册').fontColor(Color.Orange).fontSize(40)

          TextInput({ placeholder: "请输入注册的账号" })
            .placeholderColor(Color.White)
            .width(250)
            .border({
              color:Color.White,
              radius:30,
              width:1,
              style:BorderStyle.Solid
            })
            .height(60)
            .onChange(value => {
              this.account = value
            })

          TextInput({ placeholder: "请输入密码" })
            .placeholderColor(Color.White)
            .fontColor(Color.White)
            .type(InputType.Password)
            .border({
              color:Color.White,
              radius:30,
              width:1,
              style:BorderStyle.Solid
            })
            .width(250)
            .height(60)
            .onChange(value => {
              this.password =value
            })
          TextInput({ placeholder: "请再次输入密码" })
            .placeholderColor(Color.White)
            .fontColor(Color.White)
            .type(InputType.Password)
            .border({
              color:Color.White,
              radius:30,
              width:1,
              style:BorderStyle.Solid
            })
            .width(250)
            .height(60)
            .onChange(value => {
              this.password2 =value
            })
          Button("注册")
            .fontColor(Color.White)
            .backgroundColor(Color.Orange)
            .width(250)
            .height(40)
            .type(ButtonType.Capsule).onClick(() => {
            if(this.password!=this.password2){
                AlertDialog.show(
                  {
                    title: '密码输入错误',
                    message: '输入密码不一致',
                    autoCancel: true,
                    alignment: DialogAlignment.Bottom,
                    offset: { dx: 0, dy: -20 },
                    gridCount: 3,
                    confirm: {
                      value: '确认',
                      action: () => {
                        console.info('Button-clicking callback')
                      }
                    },
                    cancel: () => {
                      console.info('Closed callbacks')
                    }
                  }
                )
              }else {
              router.pushUrl({
                url: 'pages/HomePage',
                params: {

                  account: this.account,
                  password: this.password

                }
              })
            }
          })


        }
        .width('100%')
      }
      .height('100%')
      .linearGradient(
        {
          angle:110,
          colors:[['#ff1661be',0,1],['#ff2ed6bd',0.8],['#ff12bf74',0.1]]
        }
      )
    }
  }
}
//重置密码
@Component
export struct Reset{
  @State account: string = ''
  @State password: string = ''
  build(){
    Column(){
      Row() {
        Column({ space: 20 }) {
          Text('重置密码').fontColor(Color.Orange).fontSize(40)
          TextInput({ placeholder: "请输入要重置的账号" })
            .placeholderColor(Color.White)
            .width(250)
            .border({
              color:Color.White,
              radius:30,
              width:1,
              style:BorderStyle.Solid
            })
            .height(60)
            .onChange(value => {
              this.account = value
            })

          TextInput({ placeholder: "请输入要重置的账号密码" })
            .placeholderColor(Color.White)
            .fontColor(Color.White)
            .type(InputType.Password)
            .border({
              color:Color.White,
              radius:30,
              width:1,
              style:BorderStyle.Solid
            })
            .width(250)
            .height(60)
            .onChange(value => {
              this.password =value
            })
          Button("重置")
            .fontColor(Color.White)
            .backgroundColor(Color.Orange)
            .width(250)
            .height(40)
            .type(ButtonType.Capsule).onClick(() => {
            AlertDialog.show(
              {
                title: '注册成功',
                message: '跳转主页',
                autoCancel: true,
                alignment: DialogAlignment.Bottom,
                offset: { dx: 0, dy: -20 },
                gridCount: 3,
                confirm: {
                  value: '确认',
                  action: () => {
                    router.pushUrl({
                      url: 'pages/Login',
                      params: {
                        account:this.account,
                        password:this.password
                      }
                    })
                  }
                },
                cancel: () => {
                  console.info('Closed callbacks')
                }
              }
            )
          })
        }
        .width('100%')
      }
      .height('100%')
      .linearGradient(
        {
          angle:110,
          colors:[['#ff1661be',0,1],['#ff2ed6bd',0.8],['#ff12bf74',0.1]]
        }
      )
    }
  }
}

代码首页

包含四个分页

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_07

 build() {
    Tabs({barPosition:BarPosition.End}) {
      TabContent() {
       Goods()
      }
      .tabBar(this.bar('主页', $rawfile('main.png'), 0))
      TabContent() {
        NewGoods()
      }
      .tabBar(this.bar('新品', $rawfile('new.png'), 1))
      TabContent() {
        BuyCar()
      }
      .tabBar(this.bar('购物车', $rawfile('shopCar.png'), 2))
      TabContent() {
      MinePage()
      }
      .tabBar(this.bar('我的', $rawfile('mine.png'), 3))
    }.onChange((index)=>{
      this.currentTabIndex=index
    })
   }
@Component
struct Goods {//实现主页分页
  @State currentTabIndex: number = 0
  build(){
    Tabs(){
      ForEach(categories,(item,index)=>{
        TabContent(){
          Grid(){
            ForEach(goods.filter(good=>good.category===this.currentTabIndex||index===0),(item,index)=>{

              GridItem() {
                GoodItem({good:item})
              }
            })
          }
          .rowsGap(6)
          .columnsGap(6)
          .columnsTemplate('1fr 1fr ')
          }.tabBar(this.bar(item.name,index))
      })
    }
    .width('90%')
    .padding({bottom:20})
    .onChange((index)=>{
      this.currentTabIndex=index
    })
  }
  @Builder
  bar(name: string,  index: number) {
    Flex({
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center
    }) {
      Text(name).fontSize(30).fontColor(0x3E3E3E).margin(10).fontColor(this.currentTabIndex === index ? '#ff1286c6' : '')
    }
  }
}
@Component
struct NewGoods {//新产品分页
  @State currentTabIndex: number = 0
  categories: Array<{
    id: number,
    name: string|Resource
  }> =
    [{ id: 1, name: '新品' } ]
  build(){
    Tabs(){
      ForEach(this.categories,(item,index)=>{
        TabContent(){
          Grid(){
            ForEach(goods.filter(good=>good.isNew===1),(item,index)=>{
              GridItem() {
                GoodItem({good:item})
              }
            })
          }
          .rowsGap(6)
          .columnsGap(6)
          .columnsTemplate('1fr')
        }.tabBar(this.bar(item.name,index))
      })
    }
    .width('90%')
    .padding({bottom:20})
    .onChange((index)=>{
      this.currentTabIndex=index
    })

  }
  @Builder
  bar(name: string,  index: number) {
    Flex({
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center
    }) {
      // .backgroundColor(this.currentTabIndex === index ? '#55ff55' : '')
      Text(name).fontSize(30).fontColor(0x3E3E3E).margin(10).fontColor(this.currentTabIndex === index ? '#55ff55' : '')
    }
  }
}
@Component
export  struct BuyCar {//购物车
  goods: Array<GoodInfo> = [
    {
      id: 0,
      name: 'xx手机',
      price: 5999,
      category: 1,
      img: 'iphone1.jpg',
      count: 21,
      area: '广州',
      provider: "数码科技",
      isNew: 0,
      detail: '高性能',
      state: 0

    },
    {
      id: 1,
      name: '蓝牙耳机',
      price: 646,
      category: 1,
      img: 'airpods.jpg',
      count: 23,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '居家必备',
      state: 0

    },
    {
      id: 2,
      name: '平板',
      price: 2999,
      category: 1,
      img: 'ipad.jpg',
      count: 99,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '致敬时代',
      state: 0
    },
    {
      id: 3,
      name: '智能手表',
      price: 299,
      category: 1,
      img: 'iwacth.jpg',
      count: 32,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '智能生活助手',
      state: 0
    },
    {
      id: 4,
      name: '笔记本',
      price: 4999,
      category: 1,
      img: 'macBook.jpg',
      count: 12,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '商务轻薄笔记本',
      state: 0
    },
    {
      id: 5,
      name: '潮流衣服',
      price: 99,
      category: 2,
      img: 'cloth1.jpg',
      count: 21,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '温暖舒适',
      state: 0
    },
    {
      id: 6,
      name: '女鞋',
      price: 199,
      category: 2,
      img: 'cloth2.jpg',
      count: 24,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '轻便快捷',
      state: 0
    },
  ]
  goodInfoNew: GoodInfo = (router.getParams() as { goodInfo: GoodInfo }).goodInfo
  id1: number = (router.getParams() as { goodInfo: GoodInfo }).goodInfo.id
  @State currentTabIndex: number = 0
  categories: Array<{
    id: number,
    name: string | Resource
  }> =
    [{ id: 1, name: '购物车' }]

  build() {

    Tabs() {
      ForEach(this.goods.filter(good => good.name == this.goodInfoNew.name)
        .map(good => good.state = 1), (item, index) => {

      })
      ForEach(this.categories, (item, index) => {
        TabContent() {
          Grid() {
            ForEach(this.goods.filter(good => (good.state === 1)), (item, index) => {
              GridItem() {
                GoodItem({ good: item })

              }
            })
          }
          .rowsGap(6)
          .columnsGap(6)
          .columnsTemplate('1fr')
        }.tabBar(this.bar(item, index))

      })

    }
    .width('90%')
    .padding({ bottom: 20 })
    .onChange((index) => {
      this.currentTabIndex = index
    })

  }

  @Builder
  bar(goods: GoodInfo, index: number) {
    Flex({
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center
    }) {
      Button('提交订单').backgroundColor(Color.Red)
        .fontColor(Color.White).onClick(()=>{
        router.pushUrl({
          url:'pages/settlePage',
          params:{
            goodInfo:this.goods
          }
        })
      })



      }

    }
  }


//主页展示的仅是静态数据,写的粗糙
@Entry
@Component
export struct MinePage {

  private peopleInfo:PeopleInfo={name:'李先生',address: '东泰五街410号',
    phone: '149-7330-3277',img: 'boy.png',
    account: '123456',
    password: '123456'}
  private account = (router.getParams()?.['account'] )
  private password = (router.getParams()?.['password'])
  build() {
    Row() {
      Column() {
        Row(){
          // if (this.account =='123456'&&this.password=='123456'){
              Image($rawfile(this.peopleInfo.img)).height(50)
                .width(50)
          Column(){
            Text(this.peopleInfo.name)
            Text(this.peopleInfo.phone+this.peopleInfo.address).margin(5)
          }
        }.position({x: 10, y: 20})

      }

    }
  }
}

可以实现根据商品的类别进行分类

  『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业_08『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_09


『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业_10   『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业_11


商品详情页:

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_12

订单确认页:

『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙OS4.0_13

购物车页:


『江鸟中原』鸿蒙开发-购物车模拟应用_鸿蒙大作业_14

相关代码:

@Component
export  struct BuyCar {//购物车页
  goods: Array<GoodInfo> = [
    {
      id: 0,
      name: 'xx手机',
      price: 5999,
      category: 1,
      img: 'iphone1.jpg',
      count: 21,
      area: '广州',
      provider: "数码科技",
      isNew: 0,
      detail: '高性能',
      state: 0

    },
    {
      id: 1,
      name: '蓝牙耳机',
      price: 646,
      category: 1,
      img: 'airpods.jpg',
      count: 23,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '居家必备',
      state: 0

    },
    {
      id: 2,
      name: '平板',
      price: 2999,
      category: 1,
      img: 'ipad.jpg',
      count: 99,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '致敬时代',
      state: 0
    },
    {
      id: 3,
      name: '智能手表',
      price: 299,
      category: 1,
      img: 'iwacth.jpg',
      count: 32,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '智能生活助手',
      state: 0
    },
    {
      id: 4,
      name: '笔记本',
      price: 4999,
      category: 1,
      img: 'macBook.jpg',
      count: 12,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '商务轻薄笔记本',
      state: 0
    },
    {
      id: 5,
      name: '潮流衣服',
      price: 99,
      category: 2,
      img: 'cloth1.jpg',
      count: 21,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '温暖舒适',
      state: 0
    },
    {
      id: 6,
      name: '女鞋',
      price: 199,
      category: 2,
      img: 'cloth2.jpg',
      count: 24,
      area: '广州',
      provider: "数码科技",
      isNew: 1,
      detail: '轻便快捷',
      state: 0
    },
  ]
  goodInfoNew: GoodInfo = (router.getParams() as { goodInfo: GoodInfo }).goodInfo
  id1: number = (router.getParams() as { goodInfo: GoodInfo }).goodInfo.id
  @State currentTabIndex: number = 0
  categories: Array<{
    id: number,
    name: string | Resource
  }> =
    [{ id: 1, name: '购物车' }]

  build() {

    Tabs() {
      ForEach(this.goods.filter(good => good.name == this.goodInfoNew.name)
        .map(good => good.state = this.goodInfoNew.state), (item, index) => {

      })
      ForEach(this.categories, (item, index) => {
        TabContent() {
          Grid() {
            ForEach(this.goods.filter(good => (good.state === 1)), (item, index) => {
              GridItem() {
                GoodItem({ good: item })

              }
            })
          }
          .rowsGap(6)
          .columnsGap(6)
          .columnsTemplate('1fr')
        }.tabBar(this.bar(item, index))

      })

    }
    .width('90%')
    .padding({ bottom: 20 })
    .onChange((index) => {
      this.currentTabIndex = index
    })

  }

  @Builder
  bar(goods: GoodInfo, index: number) {
    Flex({
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center
    }) {
      Button('提交订单').backgroundColor(Color.Red)
        .fontColor(Color.White).onClick(()=>{
        router.pushUrl({
          url:'pages/settlePage',
          params:{
            goodInfo:this.goods
          }
        })
      })



      }

    }
  }
@Entry
@Component
struct SettlementPage {//订单详情页

  private goodInfo = (router.getParams() as {goodInfo: GoodInfo}).goodInfo
  private people:PeopleInfo={name:'李先生',address: '东泰五街410号',
    phone: '149-7330-3277',img: 'boy.png',
    account: '123456',
    password: '123456'}


  build() {
      Column({space:10}){
        settleTitle()
        Column() {
          Image($rawfile('position.png')).width(40).height(40).position({x: 10, y: 26})
          Text(this.people.name).fontSize(20)
          Text(this.people.phone).fontSize(20)
          Text(this.people.address).fontSize(20)
        }
        .backgroundColor(Color.White)
          .height(100)
          .width(300)
          .justifyContent(FlexAlign.SpaceBetween)
        Column(){
          Image($rawfile(this.goodInfo.img)).width(200).height(200)

          Text(this.goodInfo.name).fontSize(20)
          Text(" "+this.goodInfo.price).fontSize(20)
          Row(){
            Text('配送').fontSize(20)
            Text('标椎配送').fontSize(20)
          }.justifyContent(FlexAlign.SpaceBetween)
          Divider().width('80%')
          Row(){
            Text('发票').fontSize(20)
            Text('电子普通发票').fontSize(20)
          }.justifyContent(FlexAlign.SpaceBetween)
        }.backgroundColor(Color.White)
        .width(300)
        .height(400)
        Row(){
          Text('¥ '+this.goodInfo.price).fontColor(Color.Red).fontSize(20)
          Button('提交订单').backgroundColor(Color.Red)
            .fontColor(Color.White)
            .onClick(() => {
              this.goodInfo.state=0
                AlertDialog.show(
                  {
                    title: '提交成功',
                    message: '返回首页',
                    autoCancel: true,
                    alignment: DialogAlignment.Bottom,
                    offset: { dx: 0, dy: -20 },
                    gridCount: 3,

                    confirm: {
                      value: '确认',
                      action: () => {
                        router.pushUrl({
                          url: 'pages/HomePage',
                          params: {
                              goodInfo:this.goodInfo
                          }
                        })
                      }
                    },
                    cancel: () => {
                      console.info('Closed callbacks')
                    }
                  }
                )



            })
        }.justifyContent(FlexAlign.SpaceEvenly)
        .width(400)
        .height(80)
      }.width('100%')
      .height('100%')
      .backgroundColor('#faf7f8f7')


  }
}
@Component
struct settleTitle {
  build() {
    Row() {
      Image($rawfile('back.png'))
        .width(20)
        .height(20)
        .margin({right: 5})
        .onClick(() => {
          router.back()
        })
      Text('确认订单')
        .fontSize(40)
    }
    .width('100%')
    .margin({top: 8})
    .padding({left: 20})
    .justifyContent(FlexAlign.Start)
  }
}
@Entry
@Component
struct Detail {//商品详情页
  private foodInfo = (router.getParams() as {foodInfo: GoodInfo}).foodInfo
  // private foodInfo = {"id":0,"name":"番茄","kk":15,"category":1,"img":{"id":16777232,"type":20000,"params":[],"bundleName":"com.example.healthydiet","moduleName":"entry"},"rl":0,"yy":0,"zf":0}

  build() {
    Column() {
      PageTitle()
      FoodImage({foodInfo: this.foodInfo})
      Content({foodInfo: this.foodInfo})
    }
    .height('100%')
    .backgroundColor('#dedede')
  }
}

@Component
struct PageTitle {
  build() {
    Row() {
      Image($rawfile('back.png'))
        .width(20)
        .height(20)
        .margin({right: 5})
        .onClick(() => {
          router.back()
        })
      Text('宝贝详情').fontSize(26).fontColor(0x3E3E3E)
    }
    .width('100%')
    .margin({top: 8})
    .padding({left: 20})
    .justifyContent(FlexAlign.Start)
  }
}

@Component
struct FoodImage {
  private foodInfo: GoodInfo
  build() {
    Stack() {
      Image(this.foodInfo.img)
        .objectFit(ImageFit.Contain)
      Text(this.foodInfo.name).fontSize(26).fontColor(0x3E3E3E).width('90%').position({x: 10, y: 230})
    }
    .height(300)
  }
}

@Component
struct Content {
  private foodInfo: GoodInfo
  build() {
    Column() {
      this.LineContent('#ffaaaa', '价格/件', this.foodInfo.price, '元')
      this.LineContent('#aaffaa', '数量', this.foodInfo.count, '件')
      this.LineContent('#aaaaff', '地区', this.foodInfo.area, '')
    }
    .width('90%')
    .margin({top: 20, bottom: 20})
    .padding(20)
    .borderRadius(10)
    .backgroundColor(Color.White)
  }

  @Builder
  LineContent(color: ResourceColor, name: string, count: number|string, unit: string) {
    Row() {
      Circle({width: 6, height: 6})
        .margin({right: 12})
        .fill(color)
      Text(name).fontSize(22).fontColor(0x3E3E3E)
      Blank()
      Text(count + ' ' + unit).fontSize(22).fontColor(0x3E3E3E)
    }
    .width('100%')
    .margin(10)
    .padding({left: 10, right: 10})
  }
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月08日 0

暂无评论

YndFXHXIcSpZ