vue 實現購物車
阿新 • • 發佈:2018-12-16
<template> <div> <div class="shopcart"> <div class="content"> <div class="content-left" @click="toggleShow"> <div class="logo-wrapper"> <div class="logo" :class="{highlight: totalCount}"> <i class="iconfont icon-shopping_cart" :class="{highlight: totalCount}"></i> </div> <div class="num" v-if="totalCount">{{totalCount}}</div> </div> <div class="price" :class="{highlight: totalCount}">¥{{totalPrice}}</div> <div class="desc">另需配送費¥{{info.deliveryPrice}}元</div> </div> <div class="content-right"> <div class="pay" :class="payClass"> {{payText}} </div> </div> </div> <!-- 購物車列表 --> <transition name="move"> <div class="shopcart-list" v-show="listShow"> <div class="list-header"> <h1 class="title">購物車</h1> <span class="empty" @click="clearCart">清空</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"> <CartControl :food="food"/> </div> </li> </ul> </div> </div> </transition> </div> <!-- 蒙層 --> <transition name="fade"> <div class="list-mask" v-show="listShow" @click="toggleShow"></div> </transition> </div> </template> <script> import { MessageBox } from 'mint-ui' import BScroll from 'better-scroll' import {mapState, mapGetters} from 'vuex' import CartControl from '../CartControl/CartControl.vue' export default { data () { return { isShow: false } }, computed: { ...mapState(['cartFoods', 'info']), ...mapGetters(['totalCount', 'totalPrice']), payClass () { const {totalPrice} = this const {minPrice} = this.info return totalPrice>=minPrice ? 'enough' : 'not-enough' }, payText () { const {totalPrice} = this const {minPrice} = this.info if(totalPrice===0) { return `¥${minPrice}元起送` } else if(totalPrice<minPrice) { return `還差¥${minPrice-totalPrice}元起送` } else { return '結算' } }, listShow () { // 如果總數量為0, 直接不顯示 if(this.totalCount===0) { this.isShow = false return false } if(this.isShow) { this.$nextTick(() => { // 實現BScroll的例項是一個單例 if(!this.scroll) { this.scroll = new BScroll('.list-content', { click: true }) } else { this.scroll.refresh() // 讓滾動條重新整理一下: 重新統計內容的高度 } }) } return this.isShow } }, methods: { toggleShow () { // 只有當總數量大於0時切換 if(this.totalCount>0) { this.isShow = !this.isShow } }, clearCart () { MessageBox.confirm('確定清空購物車嗎?').then(action => { this.$store.dispatch('clearCart') }, () => {}); } }, components: { CartControl } } </script> <style lang="less" rel="stylesheet/less" scoped> @import "../../common/lesses/mixins.less"; //只寫了購物車列表和蒙層的動畫樣式 .shopcartlist { position: absolute; left: 0; top: 0; z-index: -1; width: 100%; transition: translateY(-100%); &.move-enter-active, &.move-leave-active { transition: transform 0.5s; } &.move-enter, &.move-leave-to { transform: translateY(0) } .list-header { height: 40px; line-height: 40px; padding: 0 18px; background: #f3f5f7; border-bottom: 1px solid rgba(7, 17, 27, 0.1); .title { float: left; font-size: 14px; color: rgb(7, 17, 27); } empty { float: right; font-size: 12px; color: rgb(0, 160, 220); } } .list-content { padding: 0 18px; max-height: 217px; overflow: hidden; background: #fff; .food { position: rlative; padding: 12px 0; box-sizing: border-box; .bottom-border-1px(rgba(7, 17, 27, 0.1)); .name { line-height: 24px; font-size: 14px; color: rgb(7, 17, 27); } .price { position: absolute; right: 90px; bottom: 12px; line-height: 24px; font-size: 14px; font-weight: 700; color: rgb(240, 20, 20); } .cartcontrol-wrapper { position: absolute; right: 0; bottom: 6px; } } } } .list-mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 40; backdrop-filter: blur(10px); opacity: 1; background: rgba(7, 17, 27, 0.6); &.fade-enter-active, &.fade-leave-active { transition: all 0.5s; } &.fade-enter, &.fade-leave-to { opacity: 0; background: rgba(7, 17, 27, 0.1); } } </style>