shopcart.vue購物車

html代碼

<template>
<!--vue的render渲染須要有一個root的根dom層,因此建立一個單獨的div來包裹-->
  <div>
  <!--這是shopcart的主代碼-->
    <div class="shopcart">
    <!--用toggleList點擊顯示隱藏購物車列表-->
      <div class="content" @click="toggleList">
        <div class="content-left">
          <div class="logo-wrapper">
            <div class="logo" :class="{'highlight':totalCount>0}">
              <i class="icon-shopping_cart" :class="{'highlight':totalCount>0}"></i>
            </div>
            <div class="num" v-show="totalCount>0">{{totalCount}}</div>
          </div>
          <div class="price" :class="{'highlight':totalPrice>0}">¥{{totalPrice}}</div>
          <div class="desc">另需配送費¥{{deliveryPrice}}元</div>
        </div>
        <!--支付-->
        <div class="content-right" @click.stop.prevent="pay">
        <!--這裏class綁定的是一個payClass計算屬性-->
          <div class="pay" :class="payClass">
            {{payDesc}}
          </div>
        </div>
      </div>
      <!--省略了ball-container是動畫小球的部分-->
      <!--shopcart的列表詳情部分-->
      <transition name="fold">
        <div class="shopcart-list" v-show="listShow">
          <div class="list-header">
            <h1 class="title">購物車</h1>
            <span class="empty" @click="empty">清空</span>
          </div>
          <div class="list-content" ref="listContent">
            <ul>
              <li class="food" v-for="food in selectFoods">
                <span class="name">{{food.name}}</span>
                <div class="price">
                  <span>¥{{food.price * food.count}}</span>
                </div>
                <!--列表裏面能夠進行操做,因此會複用一個cartcontrol的組件-->
                <div class="cartcontrol-wrapper">
                  <cartcontrol @add="addFood" :food="food"></cartcontrol>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </transition>
    </div>
    <!--打開shopcart列表的時候背景須要虛化而且動畫-->
    <transition name="fade">
      <div class="list-mask" @click="hideList" v-show="listShow"></div>
    </transition>
  </div>
</template>

js代碼

import BScroll from 'better-scroll';
  import cartcontrol from '../../components/cartcontrol/cartcontrol';

  export default{
    props: {
      selectFoods: {
        type: Array,
        default(){ //data必須是一個函數,這是默認值data的寫法
          return [ 
            {}
          ];
        }
      },
      deliveryPrice: { 
        type: Number,
        default: 0
      },
      minPrice: {
        type: Number,
        default: 0
      }
    },
    data(){
      return {
        fold: true //經過這個變量來控制隱藏和顯示購物車列表,true表明隱藏,摺疊起來
      }
    },
    computed: {
      totalPrice(){ //計算總價
        let total = 0;
        this.selectFoods.forEach((food) => {
          total += food.price * food.count; //這個count就是在goods組件裏面添加的
        })
        return total;
      },
      totalCount(){ //計算總數量
        let count = 0;
        this.selectFoods.forEach((food) => {
          count += food.count;
        })
        return count;
      },
      payDesc(){ //只是簡單的作一些支付顯示的計算
        if (this.totalPrice === 0) {
          return `¥${this.minPrice}元起送`;
        } else if (this.totalPrice < this.minPrice) {
          let diff = this.minPrice - this.totalPrice;
          return `還差¥${diff}元配送`;
        } else {
          return `去結算`;
        }
      },
      payClass(){
        if (this.totalPrice < this.minPrice) {
          return 'not-enough';
        } else {
          return 'enough';
        }
      },
      listShow(){ //自動計算購物車列表是否顯示和隱藏
        if (!this.totalCount) { //自動判斷商品數量爲空
          this.fold = true; //直接隱藏
          return false;
        }
        let show = !this.fold; //當flod爲false的時候顯示購物車列表
        if (show) { 
          this.$nextTick(() => { //異步執行滾動列表初始化
            if (!this.scroll) {
              this.scroll = new BScroll(this.$refs.listContent, {
                click: true
              });
            } else {
              this.scroll.refresh();
            }
          });
        }
        return show;
      }
    },
    methods: {
      toggleList(){
        if (!this.totalCount) {
          return;
        }
        this.fold = !this.fold;
      },
      empty() { //經過清空數據屬性來控制購物車清空
        this.selectFoods.forEach((food) => {
          food.count = 0;
        });
      },
      hideList() {
        this.fold = true;
      },
      pay() {
        if (this.totalPrice < this.minPrice) {
          return;
        }
        window.alert(`支付${this.totalPrice}元`);
      }
    },
    components: {
      cartcontrol
    }
  }
  • 購物車列表的顯示和隱藏(摺疊)是經過數據fold來決定的,他是經過計算屬性listshow來實現的,這樣達到了不用操做dom就能夠改變dom行爲的效果,vue的數據驅動設計.css

  • 清空按鈕也是這樣實現的,經過批量設置count屬性來實現html

  • 拋物線小球部分參考:關於購物車添加按鈕的動畫vue

  • 由於打開shopcart詳情頁會出現兩個內容:segmentfault

css代碼

@import "../../common/stylus/mixin.styl"

  .shopcart
    position: fixed //這是固定在頁面底部的購物車欄目
    left: 0
    bottom: 0
    z-index: 50 
    width: 100%
    height: 48px
    .content
      display: flex //flex佈局
      background: #141d27
      font-size: 0
      .content-left
        flex: 1
        .logo-wrapper
          display: inline-block
          position: relative
          top: -10px //由於要凸出購物車欄目一點點,設計須要
          margin: 0 12px
          padding: 6px
          width: 56px //由於使用了border-box的關係,能夠直接寫設計的尺寸
          height: 56px
          box-sizing: border-box //border-box能夠省去計算border和內邊距
          vertical-align: top
          border-radius: 50%
          background: #141d27
          .logo
            width: 100%
            height: 100%
            border-radius: 50%
            text-align: center
            background: #2b343c
            &.highlight
              background: rgb(0, 160, 220)
            .icon-shopping_cart
              line-height: 44px
              font-size: 24px
              color: #80858a
              &.highlight
                color: #ffffff
          .num
            position: absolute
            top: 0
            right: 0
            width: 24px
            height: 16px
            line-height: 16px
            text-align: center
            border-radius: 16px
            font-size: 9px
            color: #ffffff
            background: rgb(240, 20, 20)
            box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4)
        .price
          display: inline-block
          vertical-align: top
          margin-top: 12px
          line-height: 24px
          padding-right: 12px
          box-sizing: border-box
          border-right: 1px solid rgba(255, 255, 255, 0.1)
          font-size: 16px
          font-weight: 700
          color: rgba(255, 255, 255, 0.4)
          &.highlight
            color: #ffffff
        .desc
          display: inline-block
          vertical-align: top
          margin: 12px 0 0 12px
          line-height: 24px
          color: rgba(255, 255, 255, 0.4)
          font-size: 10px
      .content-right
        flex: 0 0 105px //flex佈局固定右邊空間
        width: 105px
        .pay
          height: 48px
          line-height: 48px
          text-align: center
          font-size: 12px
          color: rgba(255, 255, 255, 0.4)
          font-weight: 700
          &.not-enough
            background: #2b333b
          &.enough
            background: #00b43c
            color: #ffffff
//省略了小球動畫的css

clipboard.png

  • 這裏主要注意border-box的使用,舉例logo-wrapperide

    • 寬高都是56px,而且須要實現內邊距是6px函數

    • 不用border-box的話,就要計算圖片的區域是多大,而後加上6px內邊距等於56px組件化

    • 用了border-box的話,就不須要計算圖片區域了,直接寫56px,即便加上6px內邊距也不撐大56px的區域,只會自動縮小內部圖片區域的區域,實際狀況就是外框區域56px,內邊距6px,圖片自動縮小到44px(6+44+6等於56)

相關文章
相關標籤/搜索