当前位置: 首页 > 科技观察

HarmonyOSArkTS电商项目实践:买什么

时间:2023-03-13 16:10:18 科技观察

了解更多开源请访问:开源基础软件社区https://ost.51cto.com项目介绍最近HarmonyOS更新了,我把是时候写一个电商项目《买什么》Demo来动手实践了。本项目只是一个UI页面,数据都是本地的假数据,没有网络数据交互。页面包括:首页、分类、购物车、我的资料、详情页。该项目基于鸿蒙ArkUI框架TS扩展的声明式开发范式。语法和概念请参考官网官方文档地址:基于TS扩展的声明式开发范式。工具版本:DevEcoStudio3.1Canary1。SDK版本:3.1.9.7(API版本8发布)。效果演示页面使用容器组件解析主框架:Tabs、TabContent,作为主框架,底部Tab使用自定义布局样式,设置点击事件,每次点击时替换选中的索引。切换内容页面。使用自定义组件实现:首页、分类、购物车、我的构建。@Entry@ComponentstructMainFrame{@StateselectIndex:number=0privatecontroller:TabsController=newTabsController()privatetabBar=getTabBarList()//内容@BuilderContent(){Tabs({controller:this.controller}){TabContent(){HomeComponent()}TabContent(){ClassifyComponent()}TabContent(){ShoppingCartComponent({isShowLeft:false})}TabContent(){MyComponent()}}.width('100%').height(0)。animationDuration(0).layoutWeight(1).scrollable(false).barWidth(0).barHeight(0)}//底部导航@BuilderTabBar(){Row(){ForEach(this.tabBar,(item:TabBarModel,index)=>{Column(){Image(this.selectIndex===index?item.iconSelected:item.icon).width(23).height(23).margin({right:index===2?3:0})Text(item.name).fontColor(this.selectIndex===index?'#dc1c22':'#000000').margin({left:1,top:2})}.layoutWeight(1).onClick(()=>{this.selectIndex=indexthis.controller.changeIndex(index)})},item=>item.name)}.width('100%').height(50).shadow({radius:1,color:'#e3e2e2',offsetY:-1})}build(){Column(){this.Content()this.TabBar()}.width('100%').height('100%')}}由于首页顶部标题栏需要悬浮在内容上方,根布局使用容器组件Stack,内容布局最外层使用容器组件Scroll实现滑动。整体内容分为3部分:Carousel:使用容器组件Swiper菜单:使用容器组件Flex,默认水平布局,子布局宽度分为五等份,设置Flex参数:wrap:FlexWrap.Wrap可以实现自动换行包装。商品列表:实现方式与菜单相同,只是宽度一分为二。向下滑动时标题栏显示功能:使用容器组件Scroll的属性方法:onScroll判断y轴方向的偏移量,根据偏移量计算比例,改变标题栏的透明度。以下是部分代码:@ComponentexportstructHomeComponent{//滑动y偏移privateyTotalOffset=0//标题栏透明度@StatetitleBarOpacity:number=0//轮播列表privatebanners=[$r("app.media.banner1"),$r("app.media.banner2"),$r("app.media.banner3"),$r("app.media.banner4"),$r("app.media.banner5"),$r("app.media.banner6"),]//菜单列表privatemenuList=getHomeMenuList()//产品列表privategoodsList:Array=getHomeGoodsList()//carousel@BuilderBanner(){...}//菜单@BuilderMenu(){....}//产品列表@BuilderGoodsList(){...}build(){Stack({alignContent:Alignment.Top}){Scroll(){Column(){this.Banner()this.Menu()this.GoodsList()}.backgroundColor(Color.White)}.scrollBar(BarState.Off).onScroll((xOffset,yOffset)=>{this.yTotalOffset+=yOffsetconstyTotalOffsetVP=px2vp(this.yTotalOffset)//旋转木马高度350constscale=yTotalOffsetVP/200this.titleBarOpacity=scale})Row(){TitleBar({title:'Home',isShowLeft:false,isShowRight:true,rightImage:$r('app.media.search')})}.opacity(this.titleBarOpacity)}.width('100%').height('100%')}}详情页和首页类似。根布局使用容器组件Stack,最外层内容布局使用容器组件Scroll实现滑动,因为详情页面布局相同,使用装饰器@Builder抽象掉通用布局。向下滑动时,标题栏显示功能原理与首页相同。以下是部分代码:importrouterfrom'@ohos.router';@Entry@ComponentstructGoodsDetail{....//carouselmap@BuilderBanner(){...}//contentitem@BuilderContentItem(title:string,content:string,top=1){Row(){Text(title).fontSize(13).fontColor('#808080')Text(content).fontSize(13).margin({left:10}).fontColor('#ff323232')Blank()Image($r('app.media.arrow')).width(12).height(18)}.width('100%').padding(13))。backgroundColor(Color.White).margin({top:top})}//Content@BuilderContent(){...this.ContentItem('postage','80件以上包邮',7)this.ContentItem('优惠','立减5元')this.ContentItem('规格','山核桃曲奇;x3',7)this.ContentItem('外送','北京市朝阳区达塔路33号')}//评论@BuilderComment(){...}//商品参数项@BuilderGoodsParamItem(title:string,content:string){Row(){Text(title).width(100).fontSize(13).fontColor('#808080')Text(content).fontSize(13).fontColor('#ff323232').layoutWeight(1).padding({right:20})}.width('100%').padding({top:15}).alignItems(VerticalAlign.Top)}//产品参数@BuilderGoodsParam(){...}build(){Stack(){Scroll(){Column(){this.Banner()this.Content()this.Comment()this.GoodsParam()}}.scrollBar(BarState.Off).onScroll((xOffset,yOffset)=>{this.yTotalOffset+=yOffsetconstyTotalOffsetVP=px2vp(this.yTotalOffset)//旋转木马高度350constscale=yTotalOffsetVP/350this.titleBarBgTmOpacity=1-scaleif(scale>0.4){this.titleBarBgWhiteOpacity=scale-0.2{this}.titleBarBgWhiteOpacity=0}})this.TopBottomOperateBar()}.width('100%').height('100%').backgroundColor('#F4F4F4')}}分类这个页面很简单,有左右两个容器组件List,一个宽度为30%,一个宽度为70%,使用循环渲染组件ForEach渲染列表以下是部分代码:@ComponentexportstructClassifyComponent{//搜索@BuilderSearch(){...}//内容@BuilderContent(){Row(){//左分类List(){...}.width('30%')//右分类List({scroller:this.scroller}){...}.width('70%')}.width('100%').layoutWeight(1).alignItems(VerticalAlign.Top)}build(){Column(){this.Search()this.Content()}.width('100%').height('100%').backgroundColor(Color.White)}}Shopping该界面的功能:全选、单选、删除商品、修改商品数量。选择商品后,右上角会显示删除按钮。更改项目的数量将同时更新总计的总价。使用List组件来实现一个列表。数据数组是使用装饰器@State定义的。数据更新必须是改变数组的项目。以下是部分代码:@ComponentexportstructShoppingCartComponent{...//商品详情@BuilderGoodsItem(item:ShoppingCartModel,index:number){...}build(){Column(){TitleBar()if(this.list.length>0){//listList(){...}.layoutWeight(1)//结算布局Row(){...}}else{Row(){Text('Empty~')}}.width('100%').height('100%').backgroundColor('#F4F4F4')}selectOperation(item:ShoppingCartModel,index:number){//替换元素改变数组所以页面可以更新letnewItem:ShoppingCartModel={id:item.id,image:item.image,name:item.name,category:item.category,newPrice:item.newPrice,oldPrice:item.oldPrice,count:item.count,isSelected:!item.isSelected}this.list.splice(index,1,newItem)this.calculateTotalPrice()}//加减操作addOrSubtractOperation(item:ShoppingCartModel,index:number,type:-1|1){...}//计算总ccalculateTotalPrice(){lettotal=0让selectedCount=0for(constitemofthis.list){if(item.isSelected){selectedCount++total+=item.newPrice*item.count}}this.totalPrice=totalthis.isAllSelected=selectedCount===this.list.length}}本项目结束,没有难点。都是根据官方文档和API制作的。依靠声明式UI的简洁和强大,页面构建效率非常高。项目地址:https://gitee.com/liangdidi/BuyWhatDemo。每天进步一点点,需要付出一点点努力。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。

猜你喜欢