以上效果,由四个ets文件实现,分别是容器页面。首页,购物车,我的。
页面里的数据,我是用json-server进行模拟的数据。
一、容器页面
使用组件Tabs和Tabcontent结合。
import Home from "./Home";
import ShoppingCar from "./ShoppingCar";
import My from "./My";@Entry
@Component
struct TabsExample {// 定义变量,表示当前选中的下标@State currentIndex:number = 0;@State arr:Array<Object> =[{icon:"/imgs/home.png",selectedIcon:"/imgs/home2.png",text:"首页"},{icon:"/imgs/gouwuche.png",selectedIcon:"/imgs/gouwuche2.png",text:"购物车"},{icon:"/imgs/wode.png",selectedIcon:"/imgs/wode2.png",text:"我的"}]build() {Column() {Tabs({ barPosition: BarPosition.End }) {ForEach(this.arr,(item,idx)=>{TabContent() {if(this.currentIndex==0){Home()}else if(this.currentIndex==1){ShoppingCar()}else{My()}}.tabBar({icon: (this.currentIndex==idx)?item.selectedIcon:item.icon,text:item.text})})}.width(360).height("100%").onChange((idx)=>{this.currentIndex = idx;})}.width('100%')}
}
二、首页
import http from '@ohos.net.http';
import router from '@ohos.router';interface IBook{id:string,name:string,author:string,publish:string,img:string
}@Entry
@Component// 对外开放
export default struct Home {@State books:Array<IBook> = [];@State imgs: Array<string> = [];scroller: Scroller = new Scroller()// 创建http的请求对象httpRequest = http.createHttp();// 获取轮播图数据getBanners(){this.httpRequest.request("http://localhost:3000/bannerImgs",(err,data)=>{if(!err){this.imgs = JSON.parse(data.result as string);this.initScroll();}})}// 获取书籍信息getBooks(){//发送请求this.httpRequest.request("http://localhost:3000/books",(err,data)=>{if(!err){// console.log("data",data)// data对象的result属性是数据// console.log("data.result",data.result)// JSON.parse():把字符串转成json对象。this.books = JSON.parse(data.result as string);}})}// aboutToAppear():这个生命周期钩子函数的调用时机:当本页面(组件)加载时,aboutToAppear(){this.getBooks();this.getBanners();}// 自行实现轮播图功能:initScroll(){let index = 0;let maxIndex = this.imgs.length-1;setInterval(()=>{index++;if(index>maxIndex){index = 0;}this.scroller.scrollTo({xOffset:index*400,yOffset:0,animation:{duration:1000,curve:Curve.Linear}})},2000)}build() {// 最外层使用弹性盒布局,纵向分为三部分:搜索框,滚动容器,底部。Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween }) {// 1、搜索框Search({ placeholder: '请输入您要搜索的内容', icon: "imgs/search01.png" }).searchButton('搜索').textAlign(TextAlign.Center).width("100%").height(60).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 20, weight: 400 }).textFont({ size: 30, weight: 400 }).onSubmit(()=>{console.log("onSubmit")router.pushUrl({url:"pages/SearchPage"})})Scroll() {Column() {// 1)、轮播图List({scroller:this.scroller}){ForEach(this.imgs,(item)=>{ListItem(){Image(item).width(400).height("100%")}})}.width("100%").height(250).listDirection(Axis.Horizontal)Swiper(){ForEach(this.imgs,(item)=>{Image(item).width(400).height("100%")})}// 2)、导航Grid() {GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}GridItem() {Column() {Image("https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/178015/31/13828/6862/60ec0c04Ee2fd63ac/ccf74d805a059a44.png").width(40).height(40)Text("京东超市")}}}.columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr 1fr').columnsGap(10).width('100%').backgroundColor(0xededed).height(180)// 3)、列表Column(){ForEach(this.books,(item)=>{Row(){Image(item.img).width(120).height(120).margin(20).onClick(()=>{// 跳转到详情页面的同时,传递了参数:bookidrouter.pushUrl({url:"pages/Detail",params:{bookid:item.id}})})Column(){Text(item.name).fontSize(22).width("100%").margin(10)Text(item.author).fontSize(22).width("100%").margin(10)Text(item.publish).fontSize(22).width("100%")}.width(200).height("100%")}.width("95%").height(140).margin(10).backgroundColor(0xdddddd).borderRadius(10).margin(10)})}.width("100%")}.width("100%")}.width("100%").height("100%").align(Alignment.TopStart)}.width("100%").height("100%")}
}
三、购物车
import router from '@ohos.router';
import http from '@ohos.net.http';
import {storage} from "../utils/globalData"// 自定义类型:商品类型interface IBook{isChecked?:boolean,id:string,name:string,price:number,count:number,smallJi?:number,limit?:number
}@Entry
@Component
export default struct ShoppingCar {// 定义状态// 购物车的商品@State bookList:Array<IBook> = []// 全选复选框的数据@State isAllChecked:boolean = false;// 定义一个状态,表示当前是否登录@State isLogin:boolean = storage.get("username");//获取购物车数据:getCarts(){const httpCreate = http.createHttp();httpCreate.request(`http://localhost:3000/carts`,(err,data)=>{if(!err){this.bookList = JSON.parse(data.result as string);}})}// 开闭原则:对扩展开放,对修改(逻辑)关闭。进一步解释,最好程序写成可配置的(数据就是配置项)。// 页面(组件)加载完毕aboutToAppear(){// 如果没有登录,则不获取购物车的数据if(this.isLogin){this.getCarts();}}// 更新数量updateCount(item){const httpCreate = http.createHttp();httpCreate.request(`http://localhost:3000/carts/${item.id}`,{method:http.RequestMethod.PUT,extraData:{name:item.name,price:item.price,count:item.count,smallJi:item.smallJi}},(err,data)=>{if(!err){//更新数量功后,重新获取最新数据this.getCarts();}})}// 定义加号按钮的功能addCount(item:IBook){// 点击加号按钮if(item.limit && item.count==item.limit){ //做限购的处理return;}item.count++;item.smallJi = item.count*item.price;console.log("item.count",item.count);this.bookList = [...this.bookList];this.updateCount(item);}// 定义减号按钮的功能subCount(item:IBook){// 点击减号按钮if(item.count==1){return;}item.count--;item.smallJi = item.count*item.price;console.log("item.count",item.count);this.bookList = [...this.bookList];this.updateCount(item);}// 全选功能checkAll(){// 当界面上的复选框选中状态发生变化时,数据跟着变化this.isAllChecked = !this.isAllChecked;//让其它商品的选中状态跟着同步发生变化this.bookList.forEach(item=>item.isChecked = this.isAllChecked);this.bookList = [...this.bookList];}// 反向控制全选框backCheckAll(item:IBook){console.log(item.name+"的复选框被点了")item.isChecked = !item.isChecked;// console.log("item.isChecked",item.isChecked)// 数组的api:every 表示 当数组的每一项如果都符合回调函数里写的条件时,every的返回值是true;否则,返回false。// if(this.bookList.every(item=>item.isChecked==true)===true){// this.isAllChecked= true;// }else{// this.isAllChecked = false;// }this.isAllChecked = this.bookList.every(item=>item.isChecked==true);this.bookList = [...this.bookList];}// 总计totalMoney(){// let money = 0;// this.bookList.forEach(item=>{// if(item.isChecked){// money+=item.smallJi;// }// })// return money;//return this.bookList.reduce((preValue,item)=>{return preValue+(item.isChecked?item.smallJi:0)},0)}// 删除购物车的商品deleteGoods(id){const httpCreate = http.createHttp();httpCreate.request(`http://localhost:3000/carts/${id}`,{method:http.RequestMethod.DELETE},(err,data)=>{if(!err){//删除成功后,重新获取最新数据this.getCarts();}})}// UI的描述build() {Column(){// 本页面的标签Row() {Image($r("app.media.back")).width(50).height(30).margin(20).onClick(()=>{router.back();})Blank().width(60)Text("购物车").fontSize(30).width("100%").height(60)}if(!this.isLogin){Column(){Text("亲,您还没有登录").fontSize(30).fontColor(Color.Red);Button("请登录").onClick(()=>{router.replaceUrl({url:"pages/Login",params:{from:"pages/Index",data:1}})})}}else{// 购物车的标题行Row(){Checkbox().select(this.isAllChecked).onClick(()=>{this.checkAll();})Text("名称").width(80)Text("价格").width(40)Text("数量").width(96).textAlign(TextAlign.Center)Text("小计").width(60).textAlign(TextAlign.Center)Text("删除").width(60).textAlign(TextAlign.Center)}.width("100%").height(60).backgroundColor(0xededed)// 购物车中的数据的显示ForEach(this.bookList,(item,idx)=>{Row(){Checkbox().select(item.isChecked).onClick(()=>{this.backCheckAll(item);})Text(item.name).width(65)Text(item.price.toString()).width(50).textAlign(TextAlign.Center)Counter() {Text(this.bookList[idx].count.toString())}.margin(10).onInc(() => {this.addCount(item);}).onDec(() => {this.subCount(item);})// 小计Text((this.bookList[idx].smallJi).toString()).width(55)Image("/imgs/delete.png").width(40).height(40).onClick(()=>{this.deleteGoods(item.id)})}.width("100%").height(60)})Divider().strokeWidth(10)Text(`总计:${this.totalMoney()}`)}}.width("100%").height("100%")}
}
四、我的
import {storage} from "../utils/globaldata"import router from '@ohos.router'
@Entry
@Component
export default struct My {//页面创建加载完毕aboutToAppear(){console.log("My:aboutToAppear")}// 页面显示onPageShow(){console.log("My:onPageShow")}// 页面隐藏onPageHide(){console.log("My:onPageHide")}// 销毁aboutToDisappear(){console.log("My:aboutToDisappear")}toLogin(){router.replaceUrl({url:"pages/Login",params:{from:"pages/Index",data:2}})}logout(){storage.delete("username");router.pushUrl({url:"pages/Index"})}build() {Scroll() {Column() {Row(){Image($r("app.media.back")).width(50).height(30).margin(20).onClick(()=>{router.back();})Button("去注册").onClick(()=>{router.pushUrl({url:"pages/Reg"})})Button("去登录").onClick(()=>{this.toLogin()})Button("退出登录").onClick(()=>{this.logout()})Button("修改密码").onClick(()=>{router.pushUrl({url:"pages/Password"})})}.width("100%").height(60)Row() {Image("/imgs/1.jpg").width(140).height(140).borderRadius(70).onClick(()=>{this.toLogin();})}.width("100%").height(200).margin({top: 50}).justifyContent(FlexAlign.Center)// 如果当前处于登录状态(是否保存着有用户名)if(storage.get('username')){Text(storage.get('username')).fontSize(30)Text(storage.get('phone')).fontSize(30).margin(10)}Blank().height(20)Divider().strokeWidth(2).backgroundColor(0xededed)Blank().height(20)Grid() {GridItem() {Text("待付款").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("我的订单").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("店铺关注").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr').columnsGap(10).rowsGap(10).width('95%').height(110).backgroundColor(Color.White).borderRadius(10)Blank().height(20)Divider().strokeWidth(2).backgroundColor(0xededed)Blank().height(20)Grid() {GridItem() {Text("优惠券").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("我的足迹").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("我的收藏").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("浏览记录").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("我的常卖").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}GridItem() {Text("我的推荐").fontSize(20).width(90).height(90).backgroundColor(0xededed).borderRadius(10).textAlign(TextAlign.Center)}}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr').columnsGap(10).rowsGap(10).width('95%').height(220).backgroundColor(Color.White).borderRadius(10)}.align(Alignment.Start)}.height("100%").width("100%")}
}