vue外卖十九:商家详情-底部购物车组件,购物车相关vuex状态设计、相关计算、清空购物车+滚动购物车

本文主要是介绍vue外卖十九:商家详情-底部购物车组件,购物车相关vuex状态设计、相关计算、清空购物车+滚动购物车,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、购物车基础

1)购物车状态设计cartFoods+mutation

在这里插入图片描述

store/state.js

// 所有要管理的状态数据:从页面需求分析出来,最好和api/index.js里的命名相同
export default{latitude: 40.10038, // 纬度longitude: 116.36867, // 经度address: {}, //地址相关信息对象categorys: [], // 食品分类数组shops: [], // 商家数组userInfo: {}, // 用户信息goods: [], // 商品列表ratings: [], // 商家评价列表info: {}, // 商家信息cartFoods: [], // 【1】购物车中食物的列表}

1.用于存储加入到了购物车中的food对象,即food.count加了此属性的food,放入cartFoods中
2.重点:【1-2】处

src/store/mutations.js

// 加购物车数量[INCREMENT_FOOD_COUNT](state,{food}){if(!food.count){//如果不存在数量属性则加一个// food.count=1//此操作虽能在food中加一个count属性,但视图无法更新/*可更新视图的设置新属性:Vue.set()参数:对象属性名属性值*/Vue.set(food,'count',1)// 【1】把加入了数量的食物,都放入cartFoods的状态中,用于购物车结算state.cartFoods.push(food)}else{//如果存在则直接加1food.count++}},// 减购物车数量[DECREMENT_FOOD_COUNT](state,{food}){if(food.count){//如果购物车数量>0才进行减操作,防止数量为负food.count--// 如果food.count数量减少至0了则从state.cartFoods中删除相应的food// 【2】splice(删除下标,删除数量);indexOf(food)返回对应对象的下标if(food.count===0){state.cartFoods.splice(state.cartFoods.indexOf(food),1)}}}

2)设计一个新状态用于计算加入购物车食物总数量(totalCount)、总价格(totalPrice)

getters类似computed:处理vuex中现有的状态,生成返回一个所有地方都可调用的新状态
知识点:getters的生成
reduce()函数两种返回累加值写法=>和return

store/getters.js

// getters类似computed:处理vuex中现有的状态,生成返回一个所有地方都可调用的新状态
export default{//【1】返回根据cartFoods中的food.count生成:购物车中食物的总数量,用于结算时使用totalCount(state){return state.cartFoods.reduce((total,food)=>{//【1.1】此处是用非箭头写法,需要返回一下值外面才能收到return total+food.count},0)},//【2】返回根据cartFoods中的food.count生成:购物车中食物总价格totalPrice(state){//【2.1】此处内部直接用=>total+food...代替returnreturn state.cartFoods.reduce((total,food)=>total+food.count*food.price,0)},//或: 【2.2】以上也可用totalCount生成的getter来计算购物车总价:totalPrice2(state,getters){return state.cartFoods.reduce((total,food)=>total+getters.totalCount*food.price,0)}}

3)购物车组件src/components/shopCart/shopCart.vue

<template>
<div><div class="shopcart"><div class="content"><div class="content-left"><div class="logo-wrapper"><!--5】如果购物车里商品有数量则加高亮显示类名highlight --><div class="logo " :class="{highlight:totalCount}"><!--12】点击显示购物车列表 --><i class="iconfont icon-shopping_cart" :class="{highlight:totalCount}"@click="showCarts"></i></div><div class="num">{{totalCount}}</div></div><div class="price" :class="{highlight:totalCount}">{{totalPrice}}</div><div class="desc">另需配送费¥{{info.deliveryPrice}}</div></div><div class="content-right"><!-- 【6】结合计算属性控制结算按钮颜色(/绿),显示文字(还差xx元起送/去结算) --><div class="pay" :class="payClass">{{payText}}</div></div></div><!--7】显隐购物车列表 需满足2个条件:1.isShow为true;且2.购物车总数不能为0;它们有一个为false就不显示列表,因此要用到计算属性showList对是否显示重新计算 --><div class="shopcart-list" v-show="showList"><div class="list-header"><h1 class="title">购物车</h1><span class="empty">清空</span></div><div class="list-content"><ul><li class="food" v-for="(food,index) in cartFoods" :key="index"><span class="name">{{food.name}}</span><div class="price"><span>{{food.price}}</span></div><div class="cartcontrol-wrapper"><div class="cartcontrol"><CartControl :food="food"/></div></div></li></ul></div></div></div><!--8】购物车列表蒙版:用计算属性原因同上 --><div class="list-mask" v-show="showList" @click="showCarts"></div>
</div>
</template><script>//【1】引入状态读取,getters读取助手函数import {mapState,mapGetters} from 'vuex'import CartControl from '../CartControl/CartControl' //购物车加减数量组件export default{data(){return{isShow:false, //【9】显隐购物车列表}},computed:{// 【2】引入需要的state、getters...mapState(['cartFoods','info']), //购物车里的食物对象,商家相关信息如:食物的起送金等其它信息...mapGetters(['totalCount','totalPrice']), //购物车食物总数量,购物车食物总价// 【3】购物车付款结算按钮:购物车总额>起送时显示样式:enough;// 小于时显示样式:not-enough;payClass(){const {totalPrice}=thisconst {minPrice}=this.inforeturn totalPrice>=minPrice ? 'enough' : 'not-enough'},// 【4】购物车付款结算按钮:购物车没东西时显示:xx元起送;// 未达金额时显示:还差xx元起送;达金额则显示:去结算;payText(){const {totalPrice}=thisconst {minPrice}=this.infoif(totalPrice===0){return `${minPrice}元起送`}else if(totalPrice<minPrice){return `还差${minPrice-totalPrice}元起送`}else{     return '去结算'}},// 【11】重新计算isShow,控制是否显示隐藏购物车列表showList(){/* 显示购物车列表条件:列表总数不为0 且 isShow也为true,才会显示购物车列表*/if(this.totalCount===0){/*isShow置否,防止在商家详情列表里点加时满足:count不为0 且 isShow也为true自动显示购物车列表*/this.isShow=false return false //直接返回false让}// 不为0则原样返回return this.isShow},},methods:{//【10】显隐购物车列表showCarts(){// 大于0才显示:防止显示空列表if(this.totalCount>0){       this.isShow=!this.isShow}}},components:{CartControl}}
</script><style lang="stylus" rel="stylesheet/stylus" scoped>@import "../../common/stylus/mixins.styl".shopcartposition fixedleft 0bottom 0z-index 50width 100%height 48px.contentdisplay flexbackground #141d27font-size 0color rgba(255, 255, 255, 0.4).content-leftflex 1.logo-wrapperdisplay inline-blockvertical-align topposition relativetop -10pxmargin 0 12pxpadding 6pxwidth 56pxheight 56pxbox-sizing border-boxborder-radius 50%background #141d27.logowidth 100%height 100%border-radius 50%text-align centerbackground #2b343c&.highlightbackground $green.icon-shopping_cartline-height 44pxfont-size 24pxcolor #80858a&.highlightcolor #fff.numposition absolutetop 0right 0width 24pxheight 16pxline-height 16pxtext-align centerborder-radius 16pxfont-size 9pxfont-weight 700color #ffffffbackground rgb(240, 20, 20)box-shadow 0 4px 8px 0 rgba(0, 0, 0, 0.4).pricedisplay inline-blockvertical-align topmargin-top 5pxline-height 24pxpadding-right 12pxbox-sizing border-boxfont-size 16pxfont-weight 700color #fff&.highlightcolor #fff.descdisplay inline-blockvertical-align bottommargin-bottom 15pxmargin-left -45pxfont-size 10px.content-rightflex 0 0 105pxwidth 105px.payheight 48pxline-height 48pxtext-align centerfont-size 12pxfont-weight 700color #fff&.not-enoughbackground #2b333b&.enoughbackground #00b43ccolor #fff.ball-container.ballposition fixedleft 32pxbottom 22pxz-index 200transition all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41).innerwidth 16pxheight 16pxborder-radius 50%background $greentransition all 0.4s linear.shopcart-listposition absoluteleft 0top 0z-index -1width 100%transform translateY(-100%)&.move-enter-active, &.move-leave-activetransition transform .3s&.move-enter, &.move-leave-totransform translateY(0).list-headerheight 40pxline-height 40pxpadding 0 18pxbackground #f3f5f7border-bottom 1px solid rgba(7, 17, 27, 0.1).titlefloat leftfont-size 14pxcolor rgb(7, 17, 27).emptyfloat rightfont-size 12pxcolor rgb(0, 160, 220).list-contentpadding 0 18pxmax-height 217pxoverflow hiddenbackground #fff.foodposition relativepadding 12px 0box-sizing border-boxbottom-border-1px(rgba(7, 17, 27, 0.1)).nameline-height 24pxfont-size 14pxcolor rgb(7, 17, 27).priceposition absoluteright 90pxbottom 12pxline-height 24pxfont-size 14pxfont-weight 700color rgb(240, 20, 20).cartcontrol-wrapperposition absoluteright 0bottom 6px.list-maskposition fixedtop 0left 0width 100%height 100%z-index 40backdrop-filter blur(10px)opacity 1background rgba(7, 17, 27, 0.6)&.fade-enter-active, &.fade-leave-activetransition all 0.5s&.fade-enter, &.fade-leave-toopacity 0background rgba(7, 17, 27, 0)
</style>

4)商家详情调用购物车组件src/pages/shop/goods/goods.vue

...略过
<!-- 底部购物车组件 --><ShopCart /> </div><!-- ref是标识此子组件:用于调用其内部的toggleShow()展示隐藏食物详情;:food向子组件传当前food对象 --><Food :food='food' ref="food" /></div>
</template>import ShopCart from '../../../components/ShopCart/ShopCart.vue' //底购物车按钮export default{
...
components:{CartControl,Food,ShopCart,}
}

5)效果:http://localhost:8080/#/shop/goods

0.点购物车图标显隐购物车列表
并能自动计算相关数值:

  1. 右结算按钮:满xx元配送 / 差xx配送 / 去结算
  2. 总费用计算
  3. 食品总数量计算 左侧红点
  4. 点蒙板也可关闭列表

在这里插入图片描述

二、清空购物车+滚动购物车

0.store/state.js

// 所有要管理的状态数据:从页面需求分析出来,最好和api/index.js里的命名相同
export default{cartFoods: [], // 购物车中食物的列表
}

1.store/mutation-types.js

export const CLEAR_CART = 'clear_cart' // 清空购物车

2.mutations.js

import {//【1】  引入类型CLEAR_CART,
} from './mutation-types.js'
import Vue from 'vue' //用于新增一个状态的属性,并能自动更新视图export default{...略过//【2】清空购物车[CLEAR_CART](state){// 把购物车状态中的count全部置为0state.cartFoods.forEach(food=>food.count=0)// 把购物车清空state.cartFoods=[]}}

3.actions.js

// 控制mutations
import {
略过...CLEAR_CART //【1】
} from './mutation-types.js'
import {
略过... //ajax请求
} from '../api/index.js'export default{略过...// 【2】清空购物车clearCart({commit}){commit(CLEAR_CART)}}

4.调用清空购物车components/shopCart/shopCart.vue

//【1】
<span class="empty" @click="clearCart">清空</span>import { MessageBox } from 'mint-ui' //确认提示框组件methods:{略过...//【1】调用vuex的action触发:mutation清空cartFoods[]和food.count数量[实现清空购物车]clearCart(){/*min-ui组件MessageBox.confirm('确定吗').then(fn1,fn2)fn1是点确定时执行的操作,fn2:取消时操作*/MessageBox.confirm('确认清空购物车吗').then(action=>{this.$store.dispatch('clearCart')},()=>{})    }

5. 购物车列表的滚动better-scroll components/shopCart/shopCart.vue

import BScroll from '@better-scroll/core' //滑动库methods:{
// 【11】重新计算isShow,控制是否显示隐藏购物车列表showList(){/* 显示购物车列表条件:列表总数不为0 且 isShow也为true,才会显示购物车列表*/if(this.totalCount===0){/*isShow置否,防止在商家详情列表里点加时满足:count不为0 且 isShow也为true自动显示购物车列表*/this.isShow=false return false //直接返回false让}//【重点】如果显示了就创建一个Bscroll滑动对象if(this.isShow) {this.$nextTick(() => {// 实现BScroll的实例是一个单例,// 如果创建多个就会导致里面的加减按钮一次加减多个食物数量if(!this.scroll) { //如果滚动对象不存在执行:this.scroll = new BScroll('.list-content', {click: true})} else {// 让滚动条刷新一下: 重新统计内容的高度解决第一次无法滚动问题this.scroll.refresh() }})}// 不为0则原样返回return this.isShow}}

效果:购物车列表即可滚动

这篇关于vue外卖十九:商家详情-底部购物车组件,购物车相关vuex状态设计、相关计算、清空购物车+滚动购物车的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/965192

相关文章

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求