vue 实现商城中选择规格后加入购物车组件(类似淘宝)
24人赞赏了该文章
2,377次浏览
编辑于2018年11月09日 09:33:08
最近在写一个关于商城的vue的项目,提到商城自然就会想到买东西,选择商品规格,购物车的一些需求,作为几年移动端开发经验,突然写起了前端页面,很是费劲,最终还是实现了需求,完成了功能。
一.先看下最终实现的需求页面
二.看下后台返回数据格式说明
根据商品id请求所有规格,每个颜色对应的尺码,所有组合的可能性都会返回,即使库存数辆为空,也会返回这一条记录,让前端判断是否展示,后台返回结构如下图所示:
三.具体功能要求
(1).弹出此页面时,库存,价钱为默认,颜色,尺码所有可能性展示
(2). 选中颜色时,尺码中没有对应此颜色或库存没有的要置灰,不能点击,库存数量,价钱,及商品图根据选择颜色尺码做对应的改变,先选择尺码亦是如此。
(3).选中后再次弹出要为默认选中状态,点击右上角图片,可以查看放大及要有滑动功能。
四.具体实现代码逻辑
先理下思路:要求出每种颜色对应的所有尺码对象,求出每种尺码对应的所有颜色对象,要考虑到去重,及是否选中,是否有库存
for (var i = 0; i < _this.colorsAndRules.length; i++) { allColors.push(_this.colorsAndRules[i].color) allRules.push(_this.colorsAndRules[i].size) } // 每个颜色对应尺寸设置是否有库存的标签 var newAllRules = [] for (var i = 0; i < Array.from(new Set(allRules)).length; i++) { var selColor = { 'rules': Array.from(new Set(allRules))[i], 'isHasRule': false } newAllRules.push(selColor) } for (var i = 0; i < newAllRules.length; i++) { for (var j = 0; j < _this.colorsAndRules.length; j++) { if (_this.colorsAndRules[j].size === newAllRules[i].rules) { if (_this.colorsAndRules[j].stock > 0) { newAllRules[i].isHasRule = true break } } } } _this.allRules = minSort(newAllRules)//对尺码做了排序 所有颜色同理。
页面要展示到所有颜色,尺码:
每个颜色对应所有的尺码对象,代码如下:
var selColors = [] var selRules = [] // 获取每个颜色对应的尺寸 for (var i = 0; i < _this.allColors.length; i++) { var allRules = [] for (var j = 0; j < _this.colorsAndRules.length; j++) { if (_this.allColors[i].color === _this.colorsAndRules[j].color) { allRules.push(_this.colorsAndRules[j]) } } console.log('已选中' + _this.isSelectColor) var colorAndRule if (_this.isSelectColor != '' && _this.allColors[i].color === _this.isSelectColor) { colorAndRule = { 'isSelectColor': true } } else { colorAndRule = { 'isSelectColor': false } } var eveColor = _this.allColors[i].color colorAndRule[eveColor] = allRules selColors.push(colorAndRule) }
每个尺码对应的颜色对象:
for (var i = 0; i < _this.allRules.length; i++) { var allColors = [] for (var j = 0; j < _this.colorsAndRules.length; j++) { if (_this.allRules[i].rules === _this.colorsAndRules[j].size) { allColors.push(_this.colorsAndRules[j]) } } var eveRule = _this.allRules[i].rules var colorAndRule if (_this.isSelectRule != '' && _this.allRules[i].rules === _this.isSelectRule) { colorAndRule = { 'isSelectRule': true } } else { colorAndRule = { 'isSelectRule': false } } colorAndRule[eveRule] = allColors selRules.push(colorAndRule) } _this.selectRules = selRules
点击选中颜色代码:
// 点击选中颜色 isSelectCol (index, color) { var _this = this var hasRules = [] for (var i = 0; i < _this.selectColors.length; i++) { if (index === i) { _this.selectColors[i].isSelectColor = true for (var key in _this.selectColors[i]) { if (key === color) { hasRules = _this.selectColors[i][key] _this.isSelectColor = color } } } else { _this.selectColors[i].isSelectColor = false } } // 所有尺寸全为空 for (var j = 0; j < _this.allRules.length; j++) { _this.allRules[j].isHasRule = false } // 库存中存在的致为可选 for (var i = 0; i < hasRules.length; i++) { for (var j = 0; j < _this.allRules.length; j++) { if (_this.allRules[j].rules === hasRules[i].size && hasRules[i].stock > 0) { _this.allRules[j].isHasRule = true } } if (_this.isSelectRule !== '') { if (hasRules[i].size === _this.isSelectRule) { _this.selectedGoods = hasRules[i] _this.imgUrls = hasRules[i].pictures } } } if (_this.isSelectRule === '') { _this.expressSelected = '请选择尺码' } else { _this.expressSelected = '已选' + ' ' + _this.isSelectColor + ' 尺码' + _this.isSelectRule } },
选中尺码同理
页面布局的实现:
<div class="selectGoods"> <div class="selColor"> <div class="selected">颜色分类</div> <div v-for="(item,index) in selectColors" :key="index" class="selColor"> <div class="colorSel" @click="isSelectCol(index,allColors[index].color)" v-if="allColors[index].isHasColor&&!item.isSelectColor">{{allColors[index].color}}</div> <div class="selectedColor" v-else-if="allColors[index].isHasColor&&item.isSelectColor" >{{allColors[index].color}}</div> <div class="noColorRules" v-else >{{allColors[index].color}}</div> </div> </div> <div class="selRules"> <div class="selected">选择尺码</div> <div v-for="(item,index) in selectRules" :key="index" class="selColor"> <div class="colorRules" @click="isSelectSize(index,allRules[index].rules)" v-if="allRules[index].isHasRule&&!item.isSelectRule">{{allRules[index].rules}}</div> <div class="selectedColor" v-else-if="allRules[index].isHasRule&&item.isSelectRule">{{allRules[index].rules}}</div> <!--<div class="noColorRules" v-if="!allRules[index].isHasRule">{{allRules[index].rules}}</div>--> <div class="noColorRules" v-else >{{allRules[index].rules}}</div> </div> </div> </div>
点击放大图的实现原理为,引用的mint-ui中轮播图的理念,因为前端手势比较麻烦,就用了非自动的录播图实现具体代码为:
<!--图片放大功能--> <div class="imgMask" v-if="showBigImg" @click.stop="showBigImg=!showBigImg"> <div class="showImg"> <mt-swipe :auto="0" :show-indicators="false" :continuous="false" :defaultIndex="num"> <mt-swipe-item v-for="(item,index) in imgUrls" :key="item.id"> <div class="testNum" >{{index+1+'/'+imgUrls.length}}</div> <img :src=" $headerImg+imgUrls[index]+$bigImg" class="img"/> </mt-swipe-item> </mt-swipe> </div>
我已把这块写为组件,需要源码的及不懂的地方请评论联系!写的不对的地方,请指出,并请多多包含前端小白!
本文独发金蝶云社区。
赞 24
24人点赞
还没有人点赞,快来当第一个点赞的人吧!
打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!
推荐阅读