黑马vue2项目的智慧商城,自己仿写一个鸿蒙版的
前言
需要用到黑马智慧商城接口。地址:wiki - 智慧商城-实战项目 (apifox.com)
一、使用ohpm下载三方库axios
具体教程在我之前天气预报文章查看如何使用
二、分析布局
纵向布局,除了头部的文字固定在顶部以外,其余的内容可以往下滑。
三、编写UI界面
1.顶部文字区
//顶部文字栏
Row(){
Text('鸿蒙智慧商城')
.width('100%')
.fontSize(25).fontWeight(800).fontColor(Color.White).textAlign(TextAlign.Center)
}
.width('100%').height('8%').backgroundColor("#c21401")
2.内容滚动区域
1.搜索框
//搜索块
Row(){
Search({placeholder:'搜索你要找的商品'})
.width('90%')
}.width('100%').justifyContent(FlexAlign.Center)
2.轮播图
//轮播图
Row(){
Swiper(){
ForEach(this.swiperPicList,(item:string)=>{
Image(item)
.width('100%').height('20%')
})
}.autoPlay(true)//设置自动播放
}.width('100%')
3.公告栏
//公告块
Row(){
Image(this.noticetUrl)
.width(30).height(30).margin({left:'2%'}).objectFit(ImageFit.Contain).borderRadius(10)
//跑马灯组件
Marquee({
start:true,
step:10,
loop:-1,
src:this.noticeText
})
.fontSize(20).fontColor("#ffffff")
}.width('100%').backgroundColor("#525252")
4.导航组
//导航组
Row(){
//网格布局,2行2列
Grid(){
ForEach(this.navList,(item:any)=>{
GridItem(){
Column({space:10}){
Image(item.imgUrl)
.width(60).height(60)
Text(item.text)
.fontSize(14)
}
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(5)
.rowsGap(5)
.width('100%')
.height(200)
}.width('100%')
5.广告图
//广告块
Row(){
Image(this.adPicUrl)
.width('100%').height('15%')
}.width('100%')
6.文字信息
//文字提示块
Row({space:20}){
Divider().width('20%')
Text('猜你喜欢').fontSize(17).fontWeight(600)
Divider().width('20%')
}.width('100%').justifyContent(FlexAlign.Center).margin({top:'5%'})
7.商品区
//商品区
Column({space:10}){
ForEach(this.goodsList,(item:any)=>{
//组件和组件传值
goods({name:item.name,imgUrl:item.imgUrl,nowPrice:item.nowPrice,sales:item.sales})
})
}.width('100%').margin({top:'5%'})
8.商品组件
获取父组件传递过来的值,使用@prop修饰器,单向传递
@Component
export struct goods{
@Prop imgUrl:string
@Prop name:string
@Prop nowPrice:string
@Prop sales:number
build(){
Row({space:30}){
Image(this.imgUrl)
.width('30%')
Column(){
// @ts-ignore
Text(this.name).width('80%').fontSize(18)
//当字体超过2行时候裁剪掉
.maxLines(2).textOverflow({overflow:TextOverflow.Clip})
Text('已售'+this.sales).fontSize(14).fontColor("#ffa9a9b3")
Text(this.nowPrice).fontColor(Color.Red).fontWeight(700)
}.width('70%').height('100%').justifyContent(FlexAlign.SpaceAround).alignItems(HorizontalAlign.Start)
}.width('98%').height('20%').backgroundColor("#F6F6F6").padding('2%')
.borderRadius(20).border({width:1})
}
}
四 、发请求获取数据
由于要获取多个数据,我么为了减少代码重复性,可以写一个通用函数
代码中包含了每条的注释,结合黑马官方接口文档,获取并赋值
async getHomeData() {
try {
// 发起API请求获取数据
const data = await axios.get('http://cba.itlike.com/public/index.php?s=/api//page/detail');
// 处理数据项的通用函数
const processItems = (index, callback) => {
const items = data.data.data.pageData.items[index].data;
items.forEach(item => callback(item));
};
// 处理轮播图数据
processItems(1, item => this.swiperPicList.push(item.imgUrl));
// 设置通知文本
this.noticeText = data.data.data.pageData.items[2].params.text;
// 处理导航列表数据
processItems(3, item => {
this.navList.push({
imgUrl: item.imgUrl,
text: item.text
});
});
// 设置广告图URL
this.adPicUrl = data.data.data.pageData.items[4].data[0].imgUrl;
// 处理商品信息数据
processItems(6, item => {
this.goodsList.push({
name: item.goods_name,
imgUrl: item.goods_image,
nowPrice: item.goods_price_min,
sales: item.goods_sales
});
});
// 标记数据准备完毕
this.isGo = true;
} catch (error) {
// 捕获并输出错误信息
console.error('发生错误:', error);
}
}
总结
1.说明
首页内容通过get请求获取数据,该接口包含较多的数组内容,赋值一定要对着接口数据来获取,获取后对变量进行赋值,再根据界面仿写UI界面即可。
可以添加一个等待获取数据效果,即在根容器上使用stack堆叠容器,默认为展示,当获取完接口数据之后,在对标志赋值,取消展示等待效果
2.完整代码
import axios from '@ohos/axios'
import { goods } from '../components/goods'
@Component
export struct Home{
//轮播图数组
@State swiperPicList:string[]=['https://tse1-mm.cn.bing.net/th/id/OIP-C.QdPHAPCpK8VeGsRtXlKLBQHaEK?w=318&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7']
//公告图标网址
@State noticetUrl:string = 'https://tse1-mm.cn.bing.net/th/id/OIP-C.St8yQ-b9wkJKYtbSZldSzgAAAA?w=176&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7'
//公告文字
@State noticeText:string = ''
//导航数组
@State navList:any[] = []
//广告图片网址
@State adPicUrl:string = ''
//商品信息数组
@State goodsList:any[] = []
//数据加载完标志
@State isGo:boolean = false
aboutToAppear(){
this.getHomeData()
}
async getHomeData() {
try {
// 发起API请求获取数据
const data = await axios.get('http://cba.itlike.com/public/index.php?s=/api//page/detail');
// 处理数据项的通用函数
const processItems = (index, callback) => {
const items = data.data.data.pageData.items[index].data;
items.forEach(item => callback(item));
};
// 处理轮播图数据
processItems(1, item => this.swiperPicList.push(item.imgUrl));
// 设置通知文本
this.noticeText = data.data.data.pageData.items[2].params.text;
// 处理导航列表数据
processItems(3, item => {
this.navList.push({
imgUrl: item.imgUrl,
text: item.text
});
});
// 设置广告图URL
this.adPicUrl = data.data.data.pageData.items[4].data[0].imgUrl;
// 处理商品信息数据
processItems(6, item => {
this.goodsList.push({
name: item.goods_name,
imgUrl: item.goods_image,
nowPrice: item.goods_price_min,
sales: item.goods_sales
});
});
// 标记数据准备完毕
this.isGo = true;
} catch (error) {
// 捕获并输出错误信息
console.error('发生错误:', error);
}
}
build(){
//层叠布局
Stack(){
if(!this.isGo){
LoadingProgress()
Text('加载数据中')
}else {
Column({space:10}){
//顶部文字栏
Row(){
Text('鸿蒙智慧商城')
.width('100%')
.fontSize(25).fontWeight(800).fontColor(Color.White).textAlign(TextAlign.Center)
}
.width('100%').height('8%').backgroundColor("#c21401")
//滚动容器
Scroll() {
Column() {
//搜索块
Row(){
Search({placeholder:'搜索你要找的商品'})
.width('90%')
}.width('100%').justifyContent(FlexAlign.Center)
//轮播图
Row(){
Swiper(){
ForEach(this.swiperPicList,(item:string)=>{
Image(item)
.width('100%').height('20%')
})
}.autoPlay(true)//设置自动播放
}.width('100%')
//公告块
Row(){
Image(this.noticetUrl)
.width(30).height(30).margin({left:'2%'}).objectFit(ImageFit.Contain).borderRadius(10)
//跑马灯组件
Marquee({
start:true,
step:10,
loop:-1,
src:this.noticeText
})
.fontSize(20).fontColor("#ffffff")
}.width('100%').backgroundColor("#525252")
//导航组
Row(){
//网格布局,2行2列
Grid(){
ForEach(this.navList,(item:any)=>{
GridItem(){
Column({space:10}){
Image(item.imgUrl)
.width(60).height(60)
Text(item.text)
.fontSize(14)
}
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(5)
.rowsGap(5)
.width('100%')
.height(200)
}.width('100%')
//广告块
Row(){
Image(this.adPicUrl)
.width('100%').height('15%')
}.width('100%')
//文字提示块
Row({space:20}){
Divider().width('20%')
Text('猜你喜欢').fontSize(17).fontWeight(600)
Divider().width('20%')
}.width('100%').justifyContent(FlexAlign.Center).margin({top:'5%'})
//商品区
Column({space:10}){
ForEach(this.goodsList,(item:any)=>{
//组件和组件传值
goods({name:item.name,imgUrl:item.imgUrl,nowPrice:item.nowPrice,sales:item.sales})
})
}.width('100%').margin({top:'5%'})
}.width('100%')
}.width('100%').height('92%').scrollBar(BarState.Off)//不显示滚动条
}
.width('100%').height('100%')
}
}
}
}