效果:增加数量不做限制,减少数量到0的时候从购物车中删除商品。

购物车数据结构:

html

<!-- 单向联动菜单 -->
<view class="scroll-box" :style="{ 'height': scrollHeight +'px' }"><!-- 左边栏 --><view class="left-tab"><scroll-view class="tab" scroll-y="true" scroll-with-animation ><block v-for="(item,index) in tabData" :key="index" ><!-- 标签动态样式 --><view class="tab-item" :class=" [currentTab==index ? 'active' : 'none'] " @click="clickTab":data-current="index" :data-title="[item.title]" >{{item.title}} </view></block>     </scroll-view></view>           <!-- 右边页面 -->         <scroll-view class="right-box" scroll-y="true" :scroll-top="scrollTop" @scroll="scroll" ><view class="page-view">                       <view class="class-item">                      <view class="item-title"><text>{{goodsTitle}}</text></view><view class="item-container"><view class="thumb-box" v-for="(item, index) in menuData" :key="index"><view class="left-image"><image class="item-menu-image" :src="item.imgUrl" mode=""></image></view><view class="right-text"><view class="item-menu-name">{{item.name}}</view><view class="item-menu-explain">{{item.explain}}</view><view class="item-menu-ps"><view class="item-menu-price">¥{{item.price}}</view><!-- Animate动画库使用 https://blog.csdn.net/qq_40976321/article/details/107379659 --><view class="item-menu-select" hover-class="animated rotateOut" @click="addCar" :data-item="[item]">加购</view></view></view>                              </view></view></view>                 </view></scroll-view>
</view><!-- 底部购物车 -->
<view class="car" v-if="isShowCar"><view class="car-left"><view class="car-pice">¥{{totalPrice}}</view></view><view class="car-right"><view class="car-text">选好了</view>   </view>
</view>
<!-- 凸起图标 -->
<view class="car-img-back" v-if="isShowCar" @click="clickCar"><image class="car-img" src="../../../static/icon/png/bag.png" mode=""></image><!-- 角标 --><view class="car-num"><text class="car-num-text">{{totalNum}}</text></view>
</view>
<!-- 购物车列表 -->
<view class="car-list" v-if="isShowList"><scroll-view scroll-y="true" style="height: 500rpx;">              <view class="car-box" v-for="(item, index) in carData" :key="index"><view class="car-left-image" style="width: 23%;"><image class="car-menu-image" :src="item.imgUrl" mode=""></image></view><view class="car-right-text" style="width: 73%;"><view class="car-menu-name">{{item.name}}</view><view class="car-menu-explain">{{item.explain}}</view><view class="car-menu-ps"><view class="car-menu-price" >¥{{item.price}}</view><view class="car-num-select" ><view @click="clickMinus(index)"> <image style="width: 48rpx;height: 48rpx;" src="../../../static/icon/png/jian.png" ></image> </view><view style="margin: 0rpx 15rpx;font-size: 28rpx;"> {{item.num}} </view><view @click="clickAdd(index)"> <image style="width: 48rpx;height: 48rpx;" src="../../../static/icon/png/jia.png" ></image> </view></view></view></view>                                </view>               </scroll-view>
</view>
<!-- 遮罩层 -->
<view class="car-mark" v-if="isShowCarMark" @click="clickCarMark"></view>

js

//点击左边类别栏事件
clickTab(e) {let clickIndex = e.target.dataset.current //当前标签的索引   this.currentTab = clickIndex   let tapTitle = e.target.dataset.title //获得点击的标题this.goodsTitle = tapTitle[0]              //对数组进行筛选,让右边的列表只显示对应类别的数据this.menuData = this.tempData.filter(item => item.title == this.goodsTitle)             //滚动条返回顶部this.scrollTop = 0
},  //记录滚动条位置
scroll : function(e) {this.scrollTop = e.detail.scrollTop
},//显示、隐藏购物车清单
clickCar(){this.isShowList = !this.isShowListthis.isShowCarMark = !this.isShowCarMark
},
clickCarMark(){this.isShowList = !this.isShowListthis.isShowCarMark = !this.isShowCarMark
},//**********商品加入购物车 ***************
addCar(e){//获得点击加购的商品数据let item = e.target.dataset.item[0]                 //如果购物车里的商品name = 点击数据商品name 则返回此元素下标let index = this.carData.findIndex(ev => ev.name === item.name)//如果购物车不存在相同的商品if(index === -1) {  item.num = 1  //添加数量属性num ,默认为 1【原数据没有数量字段】              this.carData.push(item)    //把商品追加进购物车                  } else { this.carData[index].num++   //存在相同的商品则数量叠加}//更新总数与总价this.allNum()this.allPrice()//显示购物车this.isShowCar = true
},//增加数量
clickAdd(index){                    this.carData[index].num = this.carData[index].num + 1this.allNum()this.allPrice()
},//减少数量,小于1时删除元素
clickMinus(index){if(this.carData[index].num > 1){this.carData[index].num = this.carData[index].num - 1                 } else {this.carData.splice(index,1) //从数组删除元素                  }   this.allNum()this.allPrice()
},// 计算商品总数量
allNum() {              let count = 0;this.carData.forEach(item=>{count+=item.num                    })this.totalNum = count//购物车有商品的时候,滚动栏高度减少,让出位置给购物车if(this.totalNum === 1 && this.isAddHeight){this.scrollHeight = this.scrollHeight - 50this.isAddHeight = false} //购物车没有商品的时候,隐藏组件,还原滚动栏高度if (this.totalNum === 0){this.scrollHeight = this.scrollHeight + 50this.isAddHeight = truethis.isShowCar = falsethis.clickCar()                    }
},  // 计算商品总价格
allPrice() {                let Price = 0;this.carData.forEach(item=>{//总价格=数量 X 单价  ,由于数组的单价是字符串类型,所以要先转换成浮点数字类型Price+=item.num * parseFloat(item.price)             })//Number类型的数据调用toFixed方法,指定保留几位小数,返回的数据是一个string类型this.totalPrice = Price.toFixed(2)
},

css

.scroll-box{display: flex;flex-direction: row;/* 需要定义高度,否则不能分栏滚动 *//* height: calc(78.2vh); */
}
.left-tab{flex: 1; /*均匀分配元素*/display: flex;overflow: hidden;background: #f6f6f6;
}
.tab{  width: 150rpx;height: 100%;}
.tab-item{  height: 100rpx;background: #f6f6f6;box-sizing: border-box;display: flex;align-items: center;justify-content: center;font-size: 22rpx;line-height: 1;
}
.active{  /* 选项卡活动时的样式 */color:#A7D500; font-weight: bolder;background: #ffffff;
}   /* 右边页面样式 */
.right-box {left: 15%;width: 80%;background: #f6f6f6;
}.page-view {padding: 10rpx;
}.class-item {margin-bottom: 30rpx;background-color: #fff;padding: 16rpx;border-radius: 8rpx;
}.item-title {font-size: 26rpx;color: $u-main-color;font-weight: bold;
}.item-container {display: flex;flex-direction: column;
}
.thumb-box {width: 98%;height: 150rpx;display: flex;flex-direction: row;align-items: center;/* justify-content: center;  */margin-top: 50rpx;
}
.item-menu-image {width: 150rpx;height: 150rpx;
}
.item-menu-name {font-weight: normal;font-size: 28rpx;margin-bottom: 10rpx;
}
.item-menu-explain{font-size: 20rpx;margin-bottom: 10rpx;/* 下方四项配合使用,超出范围的显示... */width: 400rpx;overflow: hidden;text-overflow: ellipsis;  white-space: nowrap;
}
.item-menu-ps{display: flex;flex-direction: row;justify-content: space-between; /*两边对齐*/
}
.item-menu-price{font-size: 26rpx;font-weight: 600;
}
.item-menu-select{  width: 100rpx;height: 36rpx;/* 文字垂直居中 (line-height)和(height)设置一样就可以 */line-height: 36rpx;/* 文字水平居中 */   text-align:center;font-size: 22rpx;background-color: #A7D500;border-radius: 50rpx;
}/* 购物车 */
.car{display: flex; flex-direction: row;align-items: center;    height: 100rpx;width: 100%;position: fixed; bottom: 0rpx;background-color:#ffffff ;z-index: 79;
}
.car-img-back{display: flex;flex-direction: row;align-items: center;justify-content: center;    height: 100rpx;width: 100rpx;position: fixed;bottom: 35rpx;left: 30rpx;background-color: #A7D500;border-radius: 50%;z-index: 79;
}
.car-img{height: 60rpx;width: 60rpx;
}
.car-left{/* 平均分布元素,父元素display: flex; 子元素flex:1; */flex: 1;
}
.car-pice{  padding-left: 160rpx;font-size: 34rpx;font-weight: 700;
}
.car-num{display: flex;flex-direction: row;align-items: center;justify-content: center;height: 30rpx;width: 30rpx;position: fixed;bottom: 100rpx;left: 110rpx;background-color: #ffea49;border-radius: 50%;z-index: 79;
}
.car-num-text{font-size: 20rpx;
}
.car-right{/* 平均分布元素,父元素display: flex; 子元素flex:1; */flex: 1;
}
.car-text{  height: 100rpx;width: 200rpx;line-height: 100rpx;margin-left: 200rpx;   text-align: center;background-color: #A7D500;
}
.car-list{display: flex;flex-direction: row;align-items: center;justify-content: center;height: 500rpx;width: 100%;position: fixed;bottom: 100rpx;background-color: #ffffff;    border-radius: 10px 10px 0px 0px;z-index: 78;
}.car-container {display: flex;flex-direction: column;width: 100%;
}
.car-box {width: 100%;height: 120rpx;display: flex;flex-direction: row;align-items: center;padding: 20rpx 10rpx;border-bottom: solid #f4f4f4 1px;
}
.car-menu-image {width: 100rpx;height: 100rpx;margin-left: 35rpx;
}
.car-menu-name {font-weight: normal;font-size: 28rpx;margin-bottom: 10rpx;
}
.car-menu-explain{font-size: 20rpx;margin-bottom: 10rpx;/* 下方四项配合使用,超出范围的显示... */width: 400rpx;overflow: hidden;text-overflow: ellipsis;  white-space: nowrap;
}
.car-menu-ps{display: flex;flex-direction: row;justify-content: space-between; /*两边对齐*/
}
.car-menu-price{font-size: 26rpx;font-weight: 600;
}
.car-num-select{    display: flex;flex-direction: row;width: 160rpx;height: 36rpx;
}/* 遮罩层 */
.car-mark{position: fixed;left:0;top:0;width:100%;height:100%;z-index:77;background-color: rgba(0, 0, 0, 0.4);transition: all 0.3s ease-in 0s;
}

uniapp 开发小程序购物车相关推荐

  1. uni-app 开发小程序,使用到u-charts.js时会出现弹框或下拉框部分与图标重叠的情况(还有在解决过程中出现 vasToTempFilePath: fail canvas is empty)

    如下图,是我用uni-app开发小程序时出现视图与弹框或下拉框重叠的效果图,在微信开发工具上显示正常,但到了真机上就这样. 解决措施: 在小程序中canvas层级过高,导致z-index也无法让弹窗置 ...

  2. uniapp开发小程序,引入腾讯兔小巢插件,兔小巢页面导航头部样式错乱问题

    uniapp开发小程序,引入腾讯兔小巢插件,导航头部样式错乱问题 uniapp开发小程序,引入腾讯兔小巢插件,导航头部样式错乱问题 uniapp开发微信小程序,所有页面头部导航都是自定义的,引入腾讯兔 ...

  3. uni-app开发小程序并运行起来(使用ColorUI)

    uni-app开发小程序步骤详解 最近接到一个项目 开发一个小程序 主要是早教的培训机构使用 打算用uni-app来开发小程序 到时候打包成小程序就可以了 主要是用uni-app配合colorui使用 ...

  4. uni-app开发 小程序直播功能

    uni-app开发小程序直播功能 1.微信后台申请插件开通 2.微信后台开通直播功能 3.代码中接入直播插件AppID 4.[直播组件]如何使用 5.直播组将状态获取 微信开发直播功能,需要企业账号: ...

  5. 微信小程序 - 使用 uni-app 开发小程序以及部分功能实现

    文章目录 一.uni-app 1.简介 2.开发工具 3.新建 uni-app项目 4.把项目运行到微信开发者工具 二.实现tabBar效果 1.创建tabBar页面 2.配置tabBar 三.配置网 ...

  6. uni-app开发小程序以及项目部署流程

    作者也是刚开始接触小程序开发,本次小程序开发使用的uni-app,记录下小程序的开发过程. 前期准备工作 作者使用的开发工具:HBuilder x.微信开发者工具. 创建uni-app项目 详细步骤可 ...

  7. uniapp开发小程序配置文件解析

    文章目录 前言 1.main.js 入口文件 2.App.vue 页面入口文件 2.1.应用生命周期 2.2.globalData 2.3.全局样式 3.pages.json 全局配置 3.1.pag ...

  8. Uni-app开发小程序|基于微信小程序报修系统设计与实现

    作者主页:编程指南针 作者简介:Java领域优质创作者.CSDN博客专家 .CSDN内容合伙人.掘金特邀作者.阿里云博客专家.51CTO特邀作者.多年架构师设计经验.腾讯课堂常驻讲师 主要内容:Jav ...

  9. Uniapp开发小程序引入微信快递跟踪(快递100)插件

    目录 1.小程序插件接入 2.代码示例 3.页面接收参数 4.常用快递100公司编码表 1.小程序插件接入 微信快递100插件地址:快递100-快递查询(免费接入) | 微信服务市场 (qq.com) ...

最新文章

  1. Error in x$e : $ operator is invalid for atomic vectors
  2. android staido 断点遇到的坑
  3. 9.1 基于内容的推荐系统-机器学习笔记-斯坦福吴恩达教授
  4. 调用webservice时提示对操作的回复消息正文进行反序列化时出错
  5. java服务注册中心有哪些_Spring Cloud服务注册中心简述
  6. alert点击完确定关闭浏览器窗口_为Microsoft Edge浏览器开启标签组功能
  7. 使用ESAPI 解决veracode 漏洞
  8. python 股票量化盘后分析系统V0.47
  9. 网络安全——社会工程学02
  10. Matlab中Simulink小白入门初学教程
  11. java 后端,Java后端岗位职责描述
  12. 前端小白的挖坑填坑之路。
  13. Python文件读写模式与光标的移动
  14. BI神器Power Query(18)-- PQ制作时间维度表(7)
  15. 163邮箱会员揭秘,163邮箱注册,你最想了解的几件事
  16. dell服务器硬盘简测,小巧实用性能强 戴尔MD1120磁盘柜评测
  17. cvs100e_CVS100E断路器
  18. 求Sn=a+aa+aaa...+aaaaa的值,比如2+22+222+2222+222222
  19. 亮考帮优秀作业计算机操作原理,罗教授科技教学系列十∣“对分课堂”教学法...
  20. win8计算机无法安装打印机驱动,win8怎么安装打印机驱动

热门文章

  1. 【Apollo 6.0学习笔记】感知
  2. 简单理解mAP究竟是什么
  3. Linux 设备树介绍
  4. 二、yolov5原理与源码学习
  5. 【100%通过率】华为OD机试真题 C 实现【完美走位】【2022.11 Q4新题】
  6. LED亮5秒灭5秒C语言程序代码,从单片机基础到程序框架(连载)
  7. 什么是事务以及事务的四种特性
  8. javascript sha512算法 加密
  9. 2022面试题CSS
  10. 静态数据/动态数据/使用中数据概念及数据防泄漏 隐私保护