小程序仿饿了么弹窗式购物车
2019独角兽企业重金招聘Python工程师标准>>>
效果图
包含以下模块
- 选购页实现切换分类与数量加减
- 购物车动画与同步数量加减
- 购物车弹窗自适应商品条数
一、 点击分类项,切换右边的食品,并高亮自身
这个实现比较简单,给一个states数组,用于记录每一项分类的状态,点击设为true,wxml渲染时三目运算判断即可。
categoryStates = categoryStates.map(function (item, i) {if (index == i) {item = true;} else {item = false;}return item;
});
相应的wxml文件,class="{{categoryStates[index] ? 'category-item-active' : ''}}"
二、 加减按钮
- 初始只有一个加号
- 点击加号后,相应商品数量+1,并出现减号
- 减至0时,减号消失,连同数量值
设计数组结构
cartData: {},它的键是Food表的objectId,值是数量。
以下是js代码实现
add: function (e) {// 所点商品idvar foodId = e.currentTarget.dataset.foodId;console.log(foodId);// 读取目前购物车数据var cartData = that.data.cartData;// 获取当前商品数量var foodCount = cartData[foodId] ? cartData[foodId] : 0;// 自增1后存回cartData[foodId] = ++foodCount;// 设值到data数据中that.setData({cartData: cartData});
}
在wxml文件中绑定数据如下
<view class="stepper"><!-- 减号 --><view class="symbol subtract" wx:if="{{cartData[item.objectId]}}">-</view><!-- 数量 --><view class="value">{{cartData[item.objectId]}}</view><!-- 加号 --><view class="symbol add" bindtap="add" data-food-id="{{item.objectId}}">+</view>
</view>
上述代码中,通过wx:if判断当前商品的数量是否存在,无则不显示减号按钮;而在加号按钮旁要显示的数量就是{{cartData[item.objectId]}}
;点击事件传递的foodId就是{{item.objectId}}
减法按钮类似
subtract: function (e) {// 所点商品idvar foodId = e.currentTarget.dataset.foodId;// 读取目前购物车数据var cartData = that.data.cartData;// 获取当前商品数量var foodCount = cartData[foodId];// 自减1--foodCount;// 减到零了就直接移除if (foodCount == 0) {delete cartData[foodId]} else {cartData[foodId] = foodCount;}// 设值到data数据中that.setData({cartData: cartData});
}
三、购物车动画
cascadeToggle: function () {//切换购物车开与关if (that.data.maskVisual == 'show') {that.cascadeDismiss();} else {that.cascadePopup();}
},
cascadePopup: function () {// 购物车打开动画var animation = wx.createAnimation({duration: 500,timingFunction: 'ease-in-out',});this.animation = animation;animation.translateY(-285).step();this.setData({animationData: this.animation.export(),maskVisual: 'show'});
},
cascadeDismiss: function () {// 购物车关闭动画this.animation.translateY(285).step();this.setData({animationData: this.animation.export(),maskVisual: 'hidden'});
}
通过点击控制显示与隐藏,<view class="ft" bindtap="cascadeToggle">
而<view>层级通过z-index来解决,其中底部购物车.ft区别权重最高,设为999,其次是弹窗主体.modal-content,其余默认不设定。
四、购物车加减
首先要读取购物车数据,即cartData,它是以foodId为key,数量为value的object,所以需要转换为array,才能很好地被遍历。
cartToArray: function (foodId) {// 需要判断购物车数据中是否已经包含了原商品,从而决定新添加还是仅修改它的数量var cartData = that.data.cartData;var cartObjects = that.data.cartObjects;var query = new Bmob.Query('Food');// 查询对象query.get(foodId).then(function (food) {// 从数组找到该商品,并修改它的数量for (var i = 0; i < cartObjects.length; i++) {if (cartObjects[i].food.id == foodId) {// 如果是undefined,那么就是通过点减号被删完了if (cartData[foodId] == undefined) {delete cartObjects[i];} else {cartObjects[i].quantity = cartData[foodId];}that.setData({cartObjects: cartObjects});// 成功找到直接返回,不再执行添加return ;}}// 添加商品到数组var cart = {};cart.food = food;cart.quantity = cartData[foodId];cartObjects.push(cart);that.setData({cartObjects: cartObjects});});
}
然后在add/subtract方法末尾中调用它就可以购物车键值对转换成对象数组。
那接下来就顺理成章了,直接购物车小弹窗里将cartObjects渲染就可以了。
<view class="modal-body"><view class="item" wx:for="{{cartObjects}}"><view class="title">{{item.food.title}}</view><view class="fee">{{item.food.price * item.quantity}}</view><view class="stepper"><!-- 减号 --><view class="symbol subtract" bindtap="subtract" wx:if="{{cartData[item.food.objectId]}}" data-food-id="{{item.food.objectId}}">-</view><!-- 数量 --><view class="value">{{cartData[item.food.objectId]}}</view><!-- 加号 --><view class="symbol add" bindtap="add" data-food-id="{{item.food.objectId}}">+</view></view></view>
</view>
得益于MVVM数据绑定,因此在购物车里点加减也实时地同步了商品列表中显示的数量
汇总
amount: function() {var cartObjects = that.data.cartObjects;var amount = 0;cartObjects.forEach(function (item, index) {amount += item.quantity * item.food.get('price');});that.setData({amount: amount});
}
这里多请求了一次网络,由于请求是异步的,所以我将汇总代码丢在网络请求里,于cartToArray
方法内。
减法与加法基本类似,值得一提的是,减法要判断非负的合法性,所以将自减至零时,直接将元素通过delete操作移除,省去后续提交购物车遍历汇总的非零判断的烦琐。
五、购物车高度自适应
购物车列表用的是view作为容器,这样列表是不能在弹窗里滚动的,因此要将购物车弹窗改为scroll-view显示,并且高度自适应行数,直至一个max-height高度
改造
<view class="modal-body">
替换成<scroll-view class="modal-body" scroll-y="true">
,同时在样式表中为它增加一个高度height值。
bug
过程出现了一个bug,外部的商品列表上拉时再触发购物车弹窗会出现有白屏区块。
在wxml面板查看,发现是modal-mask层随着页面滚动而上移了
果断修改样式.modal-mask {position: absolute;}
为.modal-mask {position: fixed;}
问题迎刃而解。
进一步改造
将高亮动态化,由wxss样式转移到.js代码中控制
1、先注释掉wxss中硬编码的height样式
/*弹窗主体*/
.modal-content {position: fixed;bottom: -235px;left: 0;width: 100%;/*height: 235px;*/margin-top: 5px;background: #fff;z-index: 99;
}
/*内容区域*/
.modal-body {font-size: 14px;/*height: 145px;*/max-height: 295px;
}
2、在js文件声明成员变量
// 最大行数
var max_row_height = 5;
// 行高
var cart_footer_offset = 90;
// 底部栏偏移量
var food_row_height = 49;
设定最大行数,是因为这个弹窗不能无限伸展,否则都盖过整个屏幕了;在最大行数以内,都应该自动适应高度。
3、计算高度值
// scrollHeight为商品列表本身的高度
var scrollHeight = (that.data.cartObjects.length <= max_row_height ? that.data.cartObjects.length : max_row_height) * food_row_height;
// cartHeight为整个购物车的高度,也就是包含了标题栏与底部栏的高度
var cartHeight = scrollHeight + cart_offset;
animation.translateY(- cartHeight).step();
that.setData({scrollHeight: scrollHeight,cartHeight: cartHeight
});
4、wxml绑定数据
<view animation="{{animationData}}" class="modal-content" style="height: {{cartHeight}}px; bottom: -{{cartHeight}}px;">
...<scroll-view class="modal-body" scroll-y="true" style="height: {{scrollHeight}}px;">
到此不论购物车内有几条数据,都能很好的自适应;超过5条,开始滚动视图,大功告成。
源码下载:http://git.oschina.net/laeser/dinner,或者关注公众号【黄秀杰】,回复112。
转载于:https://my.oschina.net/huangxiujie/blog/1476662
小程序仿饿了么弹窗式购物车相关推荐
- 小程序仿 axios 请求封装
一.新建request.js /** 功能:小程序仿 axios 的请求封装*/ export default class Request {// 配置项configure = {baseURL: ' ...
- 微信小程序仿微信SlideView组件slide-view
微信小程序仿微信SlideView组件. 使用 1.安装 slide-view 从小程序基础库版本 2.2.1 或以上.及开发者工具 1.02.1808300 或以上开始,小程序支持使用 npm 安装 ...
- 小程序 仿麦当劳_手机上的麦当劳和星巴克:为什么现在首先使用移动应用程序...
小程序 仿麦当劳 by James Hsu 由徐H 手机上的麦当劳和星巴克:为什么现在首先使用移动应用程序 (McDonald's and Starbucks on Your Phone: Why M ...
- Java微信运动步数排序设计_微信小程序仿微信运动步数排行(交互)
本文介绍了微信小程序仿微信运动步数排行(交互),分享给大家,也给自己留个笔记,废话不多说了,具体如下: 效果图如下: wxml: {{item.name}} {{item.steps}} wxss: ...
- android微信运动页面开发,微信小程序仿微信运动步数排行(交互)
微信小程序仿微信运动步数排行(交互) 发布时间:2020-08-20 00:51:02 来源:脚本之家 阅读:101 作者:祈澈姑娘 本文介绍了微信小程序仿微信运动步数排行(交互),分享给大家,也给自 ...
- 解决微信小程序IOS中使用picker弹出内容和手机软键盘重叠的问题
解决微信小程序IOS中使用picker弹出内容和手机软键盘重叠的问题 项目需求: 一个信息提交页面:有input输入框,有picker选择器 遇到的问题: 点击input输入框时,手机自动弹出键盘,但 ...
- 微信小程序仿网易云音乐(使用云开发,提供源码)
微信小程序仿网易云音乐(使用云开发,提供源码)!!!!!!!!!!! 源码: 链接:https://pan.baidu.com/s/1z_ZnRVbT4vjEENimi8yBQQ 提取码:u0o3 一 ...
- 微信小程序-仿朋友圈点赞评论操作面板
目录 微信小程序-仿朋友圈点赞评论操作面板 一.效果 二.实现 1.wxml实现 2.js实现 3.wxss实现 三.记录 1.dataset使用 微信小程序-仿朋友圈点赞评论操作面板 一.效果 二. ...
- 小程序仿微信聊天按住说话功能
小程序仿微信聊天按住说话功能 实现:按住说话有录音动画,上滑可取消发送,松开发送录音 录音授权判断 # .wxml <view class="btn {{touchBtn?'hover ...
最新文章
- windows api打开文件对话框
- python成绩管理系统界面-python实现简易版学生成绩管理系统
- 1、C语言面试笔试---变量定义和声明
- Visual Studio 2017 图文安装流程
- range函数python3_Python3如何使用range函数替代xrange函数
- antd4中Form.create已废弃
- cglib:缺少的手册
- python dict底层实现_dict实现原理和哈希表
- amazon rds 性能_Amazon S3 —云文件存储可提高性能并节省成本
- 微信发虎年新春贺词领福袋:游戏皮肤、QQ音乐VIP、现金红包等
- VB的doevents,制造多线程的效果
- 【Java-Web】初始化加载Serlvet工程后-HttpServlet报错
- Android 意图(Intent) 理论详解
- 人工智能常见算法简介
- 二进制数的算术运算和逻辑运算
- AES算法中S盒的FPGA实现
- 五大列级庄_波尔多1855年评定的列级名庄1-5级各有哪些?哪个产区的列级庄最多?...
- 最小二乘法拟合椭圆(椭圆拟合线)
- XTU 程序设计实践模拟考试题1
- 第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组