鸿蒙HarmonyOS Next练手学习项目购物车功能,联动全选反选、数量总计
点击商品,进行勾选商品。商品列表全部点击,全选状态为已选择,点击取消某个商品,全选状态反选。删除某个商品还没有开发,练手的小功能,记录一下
import ShopCarEntity from './ShopCarEntity'
@Entry
@Component
export default struct ShopCarPage {
@State carList: ShopCarEntity[] = []
@State totalPrice: number = 0
@State totalCount: number = 0
@State isSelectAll: boolean = false
//已选择的数量
@State selectNum: number = 0
@State isSelectOneOrAll: boolean = false
aboutToAppear(): void {
let shopCar = new ShopCarEntity()
shopCar.id = 1
shopCar.goods_id = 1
shopCar.user_id = 1
shopCar.order_id = 1
shopCar.goods_desc = '电脑'
shopCar.goods_default_price = 1
shopCar.goods_default_icon =
'https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'
this.carList.push(shopCar)
let shopCar1 = new ShopCarEntity()
shopCar1.id = 2
shopCar1.goods_id = 2
shopCar1.user_id = 2
shopCar1.order_id = 2
shopCar1.goods_desc = '手机'
shopCar1.goods_default_price = 1
shopCar1.goods_default_icon =
'https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'
this.carList.push(shopCar1)
let shopCar2 = new ShopCarEntity()
shopCar2.id = 3
shopCar2.goods_id = 3
shopCar2.user_id = 3
shopCar2.order_id = 3
shopCar2.goods_desc = '智慧屏'
shopCar2.goods_default_price = 1
shopCar2.goods_default_icon =
'https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'
this.carList.push(shopCar2)
}
/**
* 计算总价和数量
*/
countTotalNumber() {
let tempTotalPrice = 0
let tempTotalCount = 0
this.carList.forEach((item: ShopCarEntity) => {
if (item.isSelected) {
tempTotalPrice += item.goods_default_price * item.count
tempTotalCount += item.count
}
})
this.totalPrice = tempTotalPrice
this.totalCount = tempTotalCount
}
/**
* 处理商品单选操作
* @param state
*/
carItemSelectChanged(status: boolean, index: number) {
let newCarList: ShopCarEntity[] = []
//如果选择的数量等于集合数量
this.isSelectOneOrAll = false
this.carList.forEach((item: ShopCarEntity, itemIndex: number) => {
if (itemIndex === index) {
if (status === true) {
this.selectNum++
} else {
if (this.selectNum === 0) {
this.selectNum = 0
} else {
this.selectNum--
}
}
//已选数量===集合数量 就是全选状态
if (this.selectNum === this.carList.length) {
this.isSelectAll = true
this.selectNum = 0
} else {
this.isSelectAll = false
}
item.isSelected = status
item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`
}
newCarList.push(item)
})
this.carList = newCarList
//计算总价和数量
this.countTotalNumber()
}
/**
* 增加商品数量
* @param index
*/
addGoodsCount(index: number) {
let newCarList: ShopCarEntity[] = []
this.carList.forEach((item: ShopCarEntity, itemIndex: number) => {
if (itemIndex === index) {
item.count++
item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`
}
newCarList.push(item)
})
this.carList = newCarList
//只有选中商品时才计算总价和数量
if (this.carList[index].isSelected) {
this.countTotalNumber()
}
}
/**
* 减少商品数量
* @param index
*/
reduceGoodsCount(index: number) {
let newCarList: ShopCarEntity[] = []
this.carList.forEach((item: ShopCarEntity, itemIndex: number) => {
if (itemIndex === index) {
item.count--
item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`
}
newCarList.push(item)
})
this.carList = newCarList
//只有选中商品时才计算总价和数量
if (this.carList[index].isSelected) {
this.countTotalNumber()
}
}
/**
* 全选和反选
*/
selectAllCarList(selectState: boolean) {
let newCarList: ShopCarEntity[] = []
if(selectState){
//代表点击了全选
this.isSelectOneOrAll = true
}
//如果是ture 赋值
if (selectState) {
this.selectNum = this.carList.length
} else {
//点击取消全选 那就是选择数量是0
if(this.selectNum===this.carList.length){//如果是单独点击列表不能设置0
this.selectNum = 0
}
}
if (this.selectNum === this.carList.length || this.isSelectOneOrAll) {
this.carList.forEach((item: ShopCarEntity) => {
if (this.selectNum === 0 !&& selectState) {
}else{
item.isSelected = selectState
item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`
newCarList.push(item)
}
})
this.carList = newCarList
}
//计算总价和总数量
this.countTotalNumber()
}
/**
* 给ItemView生成唯一的Key
*/
generatorItemViewKey(data: ShopCarEntity): string {
if (data.itemKey) {
return data.itemKey
}
return `${data.goods_id}`
}
build() {
Flex({ direction: FlexDirection.Column }) {
//标题部分
this.TitleBarComponent()
//商品列表
this.CarListComponent()
//底部操作,只有列表有数据时才展示出来
if (this.carList.length > 0) {
this.BottomOptionsComponent()
}
}.width('100%')
.height('100%')
}
/**
* 标题部分
*/
@Builder
TitleBarComponent() {
Stack({ alignContent: Alignment.End }) {
Text('购物车')
.width('100%')
.textAlign(TextAlign.Center)
.fontColor(Color.Black)
.fontSize(16)
.fontWeight(FontWeight.Bold)
}.width('100%')
.height('56vp')
}
/**
* 商品列表
*/
@Builder
CarListComponent() {
Scroll() {
Column() {
if (this.carList.length > 0) {
List({ space: 2 }) {
ForEach(this.carList, (item: ShopCarEntity, index: number) => {
ListItem() {
this.CarItemComponent(item, index)
}
}, (item: ShopCarEntity) => this.generatorItemViewKey(item))
}
} else {
this.EmptyComponent()
}
}.width('100%').height('100%')
}.width('100%').flexGrow(1)
}
/**
* 商品ItemView组件
* @param data
*/
@Builder
CarItemComponent(data: ShopCarEntity, index: number) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
//复选框
Checkbox()
.width(20)
.height(20)
.select(data.isSelected)
.selectedColor($r('app.color.focus_color'))
.onChange((value: boolean) => {
this.carItemSelectChanged(value, index)
})
//商品主图
Image(data.goods_default_icon)
.width(100)
.margin({ left: 10, right: 10 })
.objectFit(ImageFit.Contain)
.syncLoad(true)//解决图片刷新闪烁问题
.key(data.id.toString())
//商品描述和价格
Column() {
//商品描述
Text(data.goods_desc)
.fontSize(12)
.fontColor(Color.Black)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
//价格
Text() {
Span('价格:').fontSize(12).fontColor(Color.Black)
Span(`${data.goods_default_price} 元`).fontColor($r('app.color.focus_color')).fontSize(12)
}.margin({ top: 5, bottom: 5 })
//数量加减
Row() {
Text('数量:').fontSize(12).fontColor(Color.Black)
Counter() {
Text(`${data.count}`).fontSize(12).key(data.count.toString())
}.width(100)
.height(20)
.onInc(() => {
if (data.count < 50) {
this.addGoodsCount(index)
}
})
.onDec(() => {
if (data.count > 1) {
this.reduceGoodsCount(index)
}
})
//空白组件
Blank().layoutWeight(1)
//只有当前商品选中时才显示
if (data.isSelected) {
Image($r('app.media.ic_delete')).width(15).objectFit(ImageFit.Contain).onClick(() => {
})
}
}.alignItems(VerticalAlign.Center)
}
.margin({ right: 5 })
.alignItems(HorizontalAlign.Start)
}
.padding({ left: 5, right: 5 })
.backgroundColor(Color.White)
}
@Builder
EmptyComponent() {
Column() {
Column() {
Image($r('app.media.ic_empty')).width(70).objectFit(ImageFit.Contain)
Text('您还没有添加购物车').fontColor(Color.Grey).fontSize(14).margin({ top: 5 })
}.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
/**
* 底部操作
*/
@Builder
BottomOptionsComponent() {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
//全选和总价
Row() {
Checkbox()
.width(15)
.height(15)
.select(this.isSelectAll)
.selectedColor($r('app.color.focus_color'))
.onChange((value: boolean) => {
this.isSelectAll = value
this.selectAllCarList(value)
})
Text('全选').fontColor(Color.Black).fontSize(12)
//总价
Text() {
Span('总价:').fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)
Span(`${this.totalPrice}`).fontColor($r('app.color.focus_color')).fontSize(12)
Span(' 元').fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)
Span(`(${this.totalCount}件)`).fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)
}
.textAlign(TextAlign.Start)
.margin({ left: 20 })
}
.margin({ left: 10 })
.height('100%')
//立即结算
Button('立即结算')
.width(80)
.height(35)
.fontSize(12)
.margin({ right: 10 })
.backgroundColor($r('app.color.focus_color'))
.onClick(() => {
})
}.width('100%')
.height('50vp')
.backgroundColor(Color.White)
}
}