美文网首页让前端飞前端开发那些事儿
【vue3.0】17.0 某东到家(十七)——底部购物车展开页(

【vue3.0】17.0 某东到家(十七)——底部购物车展开页(

作者: bobokaka | 来源:发表于2021-11-25 22:34 被阅读0次

    这里主要进行一些细节的优化

    全选按钮图标的居中

    首先是全选按钮图标的居中

    .product {
     ......
      &__header {
    ......
        &__all {
    ......
          &__icon {
            display: inline-block;
            vertical-align: top;
            font-size: 0.2rem;
            color: #0091ff;
          }
    
    image.png
    全选取消状态图标优化
    image.png

    更新内容如下:


    image.png

    更新Cart.vue中的icon名称,最终效果如下:


    image.png
    点击蒙层,购物车隐藏
    src\views\shop\Cart.vue
    <template>
      <!-- 蒙层 -->
      <div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
    ......
    
    样式颜色集成
    <style lang="scss" scoped>
    @import '@/style/viriables.scss';
    @import '@/style/mixins.scss';
    .mask {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      background: rgba(0, 0, 0, 0.5);
      z-index: 1;
    }
    .cart {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 2;
      background: $bg-color;
    }
    .product {
      overflow-y: scroll;
      flex: 1;
      background: $bg-color;
      &__header {
        display: flex;
        line-height: 0.52rem;
        border-bottom: 0.01rem solid $content-bg-color;
        font-size: 0.14rem;
        color: $content-font-color;
        &__all {
          width: 0.64rem;
          margin-left: 0.18rem;
          &__icon {
            display: inline-block;
            vertical-align: top;
            font-size: 0.2rem;
            margin-right: 0.05rem;
            color: $btn-bg-color;
          }
          &__text {
            display: inline-block;
            margin-left: 0.04rem;
            line-height: 0.52rem;
          }
        }
        &__clear {
          flex: 1;
          text-align: right;
          margin-right: 0.16rem;
        }
      }
      &__item {
        position: relative;
        display: flex;
        padding: 0.12rem 0.16rem;
        margin: 0 0.16rem;
        border-bottom: 0.01rem solid $content-bg-color;
        &__checked {
          line-height: 0.5rem;
          margin-right: 0.2rem;
          color: $btn-bg-color;
          i {
            font-size: 0.25rem;
          }
        }
        // 配合解决超出长度以省略号显示而不会出现换行
        &__detail {
          overflow: hidden;
        }
        &__img {
          width: 0.46rem;
          height: 0.46rem;
          margin-right: 0.16rem;
        }
        &__title {
          margin: 0;
          line-height: 0.2rem;
          font-size: 0.14rem;
          color: $content-font-color;
          // 超出长度以省略号显示而不会出现换行
          @include ellipsis;
        }
        &__price {
          margin: 0.06rem 0 0 0;
          line-height: 0.2rem;
          font-size: 0.14rem;
          color: $height-light-font-color;
        }
        &__yen {
          font-size: 0.12rem;
        }
        &__origin {
          margin-left: 0.06rem;
          line-height: 0.2rem;
          font-size: 0.12rem;
          color: $light-font-color;
          text-decoration: line-through; //中划线
        }
        // 购物车选购数量和加减号
        .product__number {
          position: absolute;
          right: 0rem;
          bottom: 0.12rem;
          &__minus,
          &__plus {
            display: inline-block;
            width: 0.2rem;
            height: 0.2rem;
            line-height: 0.16rem;
            border-radius: 50%;
            font-size: 0.2rem;
            text-align: center;
          }
          // 边框白色
          &__minus {
            border: 0.01rem solid $medium-font-color;
            color: $medium-font-color;
            margin-right: 0.05rem;
          }
          //无边框,背景蓝色
          &__plus {
            color: $bg-color;
            background: $btn-bg-color;
            margin-left: 0.05rem;
          }
        }
      }
    }
    .check {
      display: flex;
      box-sizing: border-box; //往内塞入border
      line-height: 0.49rem;
      height: 0.49rem;
      border-top: 0.01rem solid $content-bg-color;
      &__icon {
        width: 0.84rem;
        position: relative;
        &__img {
          margin: 0.12rem auto;
          display: block;
          width: 0.28rem;
          height: 0.28rem;
        }
        &__tag {
          // 乘以2然后等比例缩小
          position: absolute;
          left: 0.46rem;
          top: 0.04rem;
          padding: 0 0.04rem;
          min-width: 0.2rem;
          height: 0.2rem;
          line-height: 0.2rem;
          text-align: center;
          background-color: $height-light-font-color;
          border-radius: 0.1rem;
          font-size: 0.12rem;
          color: $bg-color;
          transform: scale(0.5);
          transform-origin: left center;
        }
      }
      &__info {
        flex: 1;
        color: $content-font-color;
        font-size: 0.12rem;
        &__price {
          line-height: 0.49rem;
          color: $height-light-font-color;
          font-size: 0.18rem;
        }
      }
      &__btn {
        width: 0.98rem;
        background-color: #4fb0f9;
        text-align: center;
        color: $bg-color;
        font-size: 0.14rem;
      }
    }
    </style>
    
    购物车详情加减号居中
      // 购物车选购数量和加减号
        .product__number {
         ......
          bottom: 0.26rem;
    
    image.png
    “清空购物车”高度撑满
    <template>
      <!-- 蒙层 -->
      <div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
      <div class="cart">
        <div class="product" v-show="showCart">
          <div class="product__header">
    ......
            <div class="product__header__clear">
              <span
                class="product__header__clear__btn"
                @click="cleanCartProducts(shopId)"
                >清空购物车</span
              >
            </div>
          </div>
    ......
    .product {
    .....
      &__header {
      .....
        &__clear {
         .....
          &__btn {
            display: inline-block;
          }
        }
      }
    
    image.png

    最终调整效果如下:

    <template>
      <!-- 蒙层 -->
      <div class="mask" v-if="showCart" @click="handleCartShowChange"></div>
      <div class="cart">
        <div class="product" v-show="showCart">
          <div class="product__header">
            <div class="product__header__all" @click="setCartItemsChecked(shopId)">
              <i
                :class="[
                  'product__header__all__icon',
                  'custom-icon',
                  allChecked
                    ? 'custom-icon-radio-checked'
                    : 'custom-icon-radio-unchecked'
                ]"
              ></i>
              <span class="product__header__all__text">全选</span>
            </div>
            <div class="product__header__clear">
              <span
                class="product__header__clear__btn"
                @click="cleanCartProducts(shopId)"
                >清空购物车</span
              >
            </div>
          </div>
          <template v-for="item in productList" :key="item._id">
            <div class="product__item" v-if="item.count > 0">
              <div
                class="product__item__checked"
                @click="changeCartItemChecked(shopId, item._id)"
              >
                <i
                  :class="[
                    'custom-icon',
                    item.checked == true
                      ? 'custom-icon-radio-checked'
                      : 'custom-icon-radio-unchecked'
                  ]"
                ></i>
              </div>
              <img class="product__item__img" :src="item.imgUrl" />
              <div class="product__item__detail">
                <h4 class="product__item__title">{{ item.name }}</h4>
                <p class="product__item__price">
                  <span class="product__item__yen"> &yen;{{ item.price }} </span>
                  <span class="product__item__origin">
                    &yen;{{ item.oldPrice }}
                  </span>
                </p>
              </div>
              <div class="product__number">
                <span
                  class="product__number__minus"
                  @click="
                    () => {
                      0
                      changeCartItemInfo(shopId, item._id, item, -1)
                    }
                  "
                  >-</span
                >
                {{ cartList?.[shopId]?.[item._id]?.count || 0 }}
                <span
                  class="product__number__plus"
                  @click="
                    () => {
                      changeCartItemInfo(shopId, item._id, item, 1)
                    }
                  "
                  >+</span
                >
              </div>
            </div>
          </template>
        </div>
        <div class="check">
          <div class="check__icon" @click="handleCartShowChange">
            <img src="/i18n/9_16/img/basket.png" alt="" class="check__icon__img" />
            <div class="check__icon__tag">
              {{ total }}
            </div>
          </div>
          <div class="check__info">
            总计:<span class="check__info__price">&yen; {{ totalPrice }}</span>
          </div>
          <div class="check__btn">去结算</div>
        </div>
      </div>
    </template>
    
    <script>
    import { ref, computed } from 'vue'
    import { useRoute } from 'vue-router' // 路由跳转方法
    import { useStore } from 'vuex' // 路由跳转方法
    import { useCommonCartEffect } from './commnCartEffect'
    
    const useCartEffect = shopId => {
      const { changeCartItemInfo } = useCommonCartEffect()
      const store = useStore()
    
      // 单个勾选或者不勾选
      const changeCartItemChecked = (shopId, productId) => {
        store.commit('changeItemChecked', { shopId, productId })
      }
      // 清除购物车按钮
      const cleanCartProducts = shopId => {
        store.commit('changeCleanCartProducts', { shopId })
      }
      // 购物车全选或者取消全选
      const setCartItemsChecked = shopId => {
        store.commit('setCartItemsChecked', { shopId })
      }
    
      // 计算shopId下所有cartList的商品数量total、价钱之和totalPrice
      const cartList = store.state.cartList // 加入购物车的商品列表fv
      const total = computed(() => {
        const productList = cartList[shopId]
        let count = 0
        if (productList) {
          for (const i in productList) {
            const product = productList[i]
            count += product.count
          }
        }
        return count
      })
      const totalPrice = computed(() => {
        const productList = cartList[shopId]
        let count = 0
        if (productList) {
          for (const i in productList) {
            const product = productList[i]
            if (product.checked === true) {
              count += product.count * product.price
            }
          }
        }
        return count.toFixed(2) // 保留2位小数
      })
    
      // 全选的计算属性
      const allChecked = computed(() => {
        const productList = cartList[shopId]
        let result = true
        if (productList) {
          for (const i in productList) {
            const product = productList[i]
            if (product.count > 0 && !product.checked) {
              result = false
              break
            }
          }
        }
        return result
      })
    
      const productList = computed(() => {
        const productInfoList = cartList[shopId] || [] // 不存在默认空数组
        return productInfoList
      })
      return {
        cartList,
        total,
        totalPrice,
        productList,
        allChecked,
        changeCartItemChecked,
        changeCartItemInfo,
        cleanCartProducts,
        setCartItemsChecked
      }
    }
    
    // 展示隐藏购物车
    const toggleCartEffect = () => {
      const showCart = ref(false)
      // 显示隐藏购物车具体内容
      const handleCartShowChange = () => {
        showCart.value = !showCart.value
      }
      return { showCart, handleCartShowChange }
    }
    export default {
      name: 'Cart',
      setup() {
        const route = useRoute()
        const shopId = route.params.id // 店铺id
        // 展示隐藏购物车
        const { showCart, handleCartShowChange } = toggleCartEffect()
        // 计算总价和加入购物车的总数量
        const {
          cartList,
          total,
          totalPrice,
          productList,
          allChecked,
          changeCartItemChecked,
          changeCartItemInfo,
          cleanCartProducts,
          setCartItemsChecked
        } = useCartEffect(shopId)
        return {
          cartList,
          total,
          totalPrice,
          productList,
          shopId,
          allChecked,
          showCart,
          handleCartShowChange,
          changeCartItemChecked,
          changeCartItemInfo,
          cleanCartProducts,
          setCartItemsChecked
        }
      }
    }
    </script>
    <style lang="scss" scoped>
    @import '@/style/viriables.scss';
    @import '@/style/mixins.scss';
    .mask {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      background: rgba(0, 0, 0, 0.5);
      z-index: 1;
    }
    .cart {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 2;
      background: $bg-color;
    }
    .product {
      overflow-y: scroll;
      flex: 1;
      background: $bg-color;
      &__header {
        display: flex;
        line-height: 0.52rem;
        border-bottom: 0.01rem solid $content-bg-color;
        font-size: 0.14rem;
        color: $content-font-color;
        &__all {
          width: 0.64rem;
          margin-left: 0.18rem;
          &__icon {
            display: inline-block;
            vertical-align: top;
            font-size: 0.2rem;
            margin-right: 0.05rem;
            color: $btn-bg-color;
          }
          &__text {
            display: inline-block;
            margin-left: 0.04rem;
            line-height: 0.52rem;
          }
        }
        &__clear {
          flex: 1;
          text-align: right;
          margin-right: 0.16rem;
          &__btn {
            display: inline-block;
          }
        }
      }
      &__item {
        position: relative;
        display: flex;
        padding: 0.12rem 0.16rem;
        margin: 0 0.16rem;
        border-bottom: 0.01rem solid $content-bg-color;
        &__checked {
          line-height: 0.5rem;
          margin-right: 0.2rem;
          color: $btn-bg-color;
          i {
            font-size: 0.25rem;
          }
        }
        // 配合解决超出长度以省略号显示而不会出现换行
        &__detail {
          overflow: hidden;
        }
        &__img {
          width: 0.46rem;
          height: 0.46rem;
          margin-right: 0.16rem;
        }
        &__title {
          margin: 0;
          line-height: 0.2rem;
          font-size: 0.14rem;
          color: $content-font-color;
          // 超出长度以省略号显示而不会出现换行
          @include ellipsis;
        }
        &__price {
          margin: 0.06rem 0 0 0;
          line-height: 0.2rem;
          font-size: 0.14rem;
          color: $height-light-font-color;
        }
        &__yen {
          font-size: 0.12rem;
        }
        &__origin {
          margin-left: 0.06rem;
          line-height: 0.2rem;
          font-size: 0.12rem;
          color: $light-font-color;
          text-decoration: line-through; //中划线
        }
        // 购物车选购数量和加减号
        .product__number {
          position: absolute;
          right: 0rem;
          bottom: 0.26rem;
          &__minus,
          &__plus {
            display: inline-block;
            width: 0.2rem;
            height: 0.2rem;
            line-height: 0.16rem;
            border-radius: 50%;
            font-size: 0.2rem;
            text-align: center;
          }
          // 边框白色
          &__minus {
            border: 0.01rem solid $medium-font-color;
            color: $medium-font-color;
            margin-right: 0.05rem;
          }
          //无边框,背景蓝色
          &__plus {
            color: $bg-color;
            background: $btn-bg-color;
            margin-left: 0.05rem;
          }
        }
      }
    }
    .check {
      display: flex;
      box-sizing: border-box; //往内塞入border
      line-height: 0.49rem;
      height: 0.49rem;
      border-top: 0.01rem solid $content-bg-color;
      &__icon {
        width: 0.84rem;
        position: relative;
        &__img {
          margin: 0.12rem auto;
          display: block;
          width: 0.28rem;
          height: 0.28rem;
        }
        &__tag {
          // 乘以2然后等比例缩小
          position: absolute;
          left: 0.46rem;
          top: 0.04rem;
          padding: 0 0.04rem;
          min-width: 0.2rem;
          height: 0.2rem;
          line-height: 0.2rem;
          text-align: center;
          background-color: $height-light-font-color;
          border-radius: 0.1rem;
          font-size: 0.12rem;
          color: $bg-color;
          transform: scale(0.5);
          transform-origin: left center;
        }
      }
      &__info {
        flex: 1;
        color: $content-font-color;
        font-size: 0.12rem;
        &__price {
          line-height: 0.49rem;
          color: $height-light-font-color;
          font-size: 0.18rem;
        }
      }
      &__btn {
        width: 0.98rem;
        background-color: #4fb0f9;
        text-align: center;
        color: $bg-color;
        font-size: 0.14rem;
      }
    }
    </style>
    

    相关文章

      网友评论

        本文标题:【vue3.0】17.0 某东到家(十七)——底部购物车展开页(

        本文链接:https://www.haomeiwen.com/subject/qxpztrtx.html