Vue 仿淘宝购物车

效果图:
这里写图片描述

这里写图片描述

我们只是做演示,其中的数据应该从后台来取得,这里我们模拟几条数据来显示。

页面布局:

 <div id="shop_car">
    <section class="car_main">
      <!--顶部列表-->
      <div class="car_head">
        <ul class="car_top">
          <li class="car_check_all">
            <input type="checkbox" id="check_all" v-model="checked_all" @click="all_products_checked"/>
            <label for="check_all">全选</label>
          </li>
          <li class="car_information">商品信息</li>
          <li class="car_price">单价</li>
          <li class="car_number">数量</li>
          <li class="car_amount">金额</li>
          <li class="car_operation">操作</li>
        </ul>
      </div>
      <!--购物车为空时展示页面-->
      <template v-if="goods.length ==  0">
        <div class="cart_empty">
          您的购物车还是空的哦,快去挑选您喜欢的东西吧.
        </div>
      </template>
      <!--购物车详情展示-->
      <template v-else>
        <div v-for="(shop,shop_index) in goods">

          <!--当店铺下面有已购买商品的时候显示该店铺和商品信息-->
          <div v-if="shop.list.length != 0">

            <!--商品详细标题-->
            <div class="shop_info">
              <ul>
                <li class="shop_info_check_all">
                  <input type="checkbox" v-model="shop.all_checked" @click="shop_all_check(shop_index)">
                </li>
                <li>
                  <img :src="shop.url" class="shop_icon"/>
                </li>
                <li>
                  <span style="margin-left: 10px;">店铺:</span>
                </li>
                <li>
                  <a :href="shop.href">{{shop.shop_name}}</a>
                </li>
                <li>
                  <img src="../../static/ShopCar/wangxin.jpg" class="shop_icon"/>
                </li>
                <li>
                  <img src="../../static/ShopCar/youhui.png" v-if="shop.discount.length != 0" class="shop_discount"/>
                </li>
              </ul>
            </div>
            <div v-for="(product,product_index) in shop.list" class="product"
                 v-bind:class="[product.product_checked ? 'selected_styles' : '']">
              <div class="product_description" v-if="product.product_description != ''">
                <div class="product_description_bg">{{product.product_description}}</div>
              </div>
              <div class="product_details">

                <!--商品是否选中-->
                <div class="product_check">
                  <input type="checkbox" v-model="product.product_checked"
                         @click="product_checked_click(shop_index,product_index)"/>
                </div>

                <!--商品图片-->
                <div class="product_img">
                  <img :src="product.url" style="width: 100px;height: 100px"/>
                </div>

                <!--商品名称-->
                <div class="product_shop_info">
                  <div class="product_shop_name">
                    <a :href="product.href">{{product.product_name}}</a>
                  </div>

                  <div class="product_shop_icon">
                    <img src="../../static/ShopCar/xcard.png" title="银联支付"/>
                    <img src="../../static/ShopCar/7day.png" title="7天内无条件退换"/>
                    <img src="../../static/ShopCar/wuyou.png" title="消费者保障服务,商家承若如实描述"/>
                  </div>
                </div>

                <!--商品尺寸颜色等属性-->
                <div class="product_type_select" @mouseenter="enter(shop_index,product_index)"
                     @mouseleave="leave(shop_index,product_index)">
                  <div class="product_type_all">
                    <div v-for="type in product.product_type" class="product_type">
                      {{type.key}}: {{type.value}}
                    </div>
                  </div>
                  <div class="product_edit" id="product_edit"
                       v-bind:class="[product.edit_type? 'product_edit_type_true':'product_edit_type_false']">
                    <button class="product_edit_button">编辑</button>
                  </div>
                </div>

                <!--商品价格-->
                <div class="product_price">
                  <div v-if="product.origin_price" class="product_price_origin">{{product.origin_price | priceFilter}}
                  </div>
                  <div class="product_price_current">{{product.current_price | priceFilter}}
                  </div>
                </div>

                <!--商品数量-->
                <div class="product_number">
                  <div class="product_number_content">
                    <div class="product_number_button">
                      <button v-if="product.number > 1" @click="product_reduce(shop_index,product_index)">-</button>
                    </div>
                    <div class="product_number_input">
                      <input type="number" v-model="product.number"  readonly/>
                    </div>
                    <div class="product_number_button" @click="product_add(shop_index,product_index)">
                      <button>+</button>
                    </div>
                  </div>
                </div>

                <!--金额统计-->
                <div class="product_amount">
                  <div class="product_total_price">{{ product_total_price(shop_index,product_index) | priceFilter}}
                  </div>
                </div>

                <!--操作选项-->
                <div class="product_operation">
                  <div>
                    <button>移入收藏夹</button>
                  </div>
                  <div>
                    <button @click="product_del(shop_index,product_index)">删除</button>
                  </div>
                  <div>
                    <button>相似宝贝</button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>
      <!--底部页面-->
      <div class="car_foot_bar">
        <div class="car_foot_settle">
          <div class="piece">已选商品 <strong class="piece_num">{{selected_products}}</strong></div>
          <div class="totalMoney">合计 (不含运费) : <strong class="total_text">{{total_amount | priceFilter}}</strong></div>
          <div class="settle_accounts">
            <button class="settle_button" :disabled="selected_products == 0 ? true : false" @click="shop_settle">
              买单
            </button>
          </div>
        </div>
      </div>
    </section>
  </div>

Vue实例:

export default {
    name: 'VShopCar',
    data() {
      return {
        goods: [
          {
            shop_name: 'cocoessence旗舰店',
            url: '../../static/ShopCar/shop.png',
            href: 'https://cocoessence.tmall.com',
            discount: ['2件9.8折'],
            all_checked: false,
            list: [
              {
                product_name: '酒店空气清新剂家用卧室持久留香卫生间除味剂除臭香薰喷香机香水',
                product_description: '空喷买2送',
                url: '../../static/ShopCar/shop1.jpg',
                href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.4.ff9a7484vD2sXY&id=527905990976',
                edit_type: false,
                product_type: [
                  {
                    id: 1,
                    key: '颜色分类',
                    value: '祖马long&middot;小苍兰(2瓶)'
                  },
                  {
                    id: 2,
                    key: '颜色分类',
                    value: '宝石蓝绿;小苍兰(2瓶)'
                  }
                ],
                current_price: 32.80,
                origin_price: 68.00,
                number: 1,
                product_checked: false,
              },
              {
                product_name: '遇见香芬COCO沐浴露持久留香72小时男女学生香水补水家庭装非美白',
                product_description: '普通商品',
                url: '../../static/ShopCar/shop2.jpg',
                href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.13.6e517484kyYSnq&id=39252128018',
                edit_type: false,
                product_type: [
                  {
                    id: 1,
                    key: '净含量',
                    value: '750ML【持久留香】',
                  }
                ],
                current_price: 36.80,
                origin_price: 98.00,
                number: 1,
                product_checked: false,
              }
            ]
          },
          {
            shop_name: 'HermanMiller旗舰',
            url: '../../static/ShopCar/shop.png',
            href: 'https://hermanmiller.tmall.com/',
            discount: [],
            all_checked: false,
            list: [
              {
                product_name: 'Herman Miller Embody 座椅 标准配置【Rhythm织物】',
                product_description: '空喷买2送',
                url: '../../static/ShopCar/shop3.jpg',
                href: 'https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.4.ff9a7484vD2sXY&id=527905990976',
                edit_type: false,
                product_type: [
                  {
                    id: 1,
                    key: '扶手类型',
                    value: '升降扶手'
                  },
                  {
                    id: 2,
                    key: '颜色分类',
                    value: '蓝莓色'
                  },
                  {
                    id: 3,
                    key: '五星脚材质',
                    value: '钢制脚'
                  }
                ],
                current_price: 9992.00,
                origin_price: 0,
                number: 1,
                product_checked: false,
              }
            ]
          },
          {
            shop_name: '佳士优电器专营店',
            url: '../../static/ShopCar/shop.png',
            href: 'https://jiashiyoudq.tmall.com/',
            discount: [],
            all_checked: false,
            list: [
              {
                product_name: 'Panasonic松下音响 无线话筒 便携扩音器WS-X66教学会议演讲培训',
                product_description: '空喷买2送',
                url: '../../static/ShopCar/shop4.jpg',
                href: 'https://jiashiyoudq.tmall.com/',
                edit_type: false,
                product_type: [
                  {
                    id: 1,
                    key: '颜色分类',
                    value: '最佳套餐WS-X66音响+wx4800话筒'
                  }
                ],
                current_price: 2950.00,
                origin_price: 3050.00,
                number: 1,
                product_checked: false,
              }
            ]
          },
          {
            shop_name: '天猫超市',
            url: '../../static/ShopCar/shoptao.png',
            href: 'https://chaoshi.tmall.com',
            discount: ['全场大促销'],
            all_checked: false,
            list: [
              {
                product_name: '韩伊橄榄Olive润肤清爽沐浴露去油沐浴乳 滋润清香洗澡液500ml\n',
                product_description: '超值换购活动',
                url: '../../static/ShopCar/shop5.jpg',
                href: 'https://chaoshi.tmall.com',
                edit_type: false,
                product_type: [
                  {
                    id: 1,
                    key: '颜色分类',
                    value: '500ml'
                  }
                ],
                current_price: 25.90,
                origin_price: 0,
                number: 1,
                product_checked: false,
              }
            ]
          }
        ],
        // 其他属性数据
        checked_all: false
      }
    },

    methods: {

      // 结算
      shop_settle() {
        alert('大哥微信支付吧,快来扫我!')
      },

      // 鼠标移入分类信息显示编辑按钮
      enter(shop_index, product_index) {
        this.goods[shop_index].list[product_index].edit_type = true;
      },

      // 鼠标移出分类信息隐藏编辑按钮
      leave(shop_index, product_index) {
        this.goods[shop_index].list[product_index].edit_type = false;
      },

      // 商品总价
      product_total_price(shop_index, product_index) {
        var product = this.goods[shop_index].list[product_index]
        return product.number * product.current_price
      },

      // 减购商品,每次减少1
      product_reduce(shop_index, product_index) {
        var product = this.goods[shop_index].list[product_index]
        if ((product.number - 1)) {
          product.number--
        }
      },

      // 加购,每次加1
      product_add(shop_index, product_index) {
        var product = this.goods[shop_index].list[product_index]
        if ((product.number + 1) < 100) {
          product.number++
        }
      },

      // 删除购买商品
      product_del(shop_index, product_index) {
        this.goods[shop_index].list.splice(product_index, 1)
      },

      // 店铺下属商品全部选择时
      shop_all_check(shop_index) {
        var shop = this.goods[shop_index]
        shop.all_checked = !shop.all_checked
        for (var i = 0; i < shop.list.length; i++) {
          shop.list[i].product_checked = shop.all_checked;
        }
      },

      // 商品选择时
      product_checked_click(shop_index, product_index) {
        var product = this.goods[shop_index].list[product_index]
        product.product_checked = !product.product_checked

        // 检测是否该店铺内的商品全选
        for (var i = 0; i < this.goods[shop_index].list.length; i++) {
          if (!this.goods[shop_index].list[i].product_checked) {
            this.goods[shop_index].all_checked = false
            this.checked_all = false
            return;
          }
        }
        this.goods[shop_index].all_checked = true

        // 检测购物车内的商品是否全部选中
        for (var i = 0; i < this.goods.length; i++) {
          if (!this.goods[i].all_checked) {
            this.checked_all = false
            return
          }
        }
        this.checked_all = true
      },

      // 检测购物车内的商品全部
      all_products_checked() {
        this.checked_all = !this.checked_all
        for (var i = 0; i < this.goods.length; i++) {
          this.goods[i].all_checked = this.checked_all
          for (var j = 0; j < this.goods[i].list.length; j++) {
            this.goods[i].list[j].product_checked = this.checked_all
          }
        }
      },
    },
    filters: {
      // 金额显示过滤 两位小数点,不足补0
      priceFilter(value) {
        var value = Math.round(parseFloat(value) * 100) / 100;
        var xsd = value.toString().split(".");
        if (xsd.length == 1) {
          value = value.toString() + ".00";
          return value;
        }
        if (xsd.length > 1) {
          if (xsd[1].length < 2) {
            value = value.toString() + "0";
          }
          return value;
        }
      }
    },

    computed: {

      // 已选择商品数目
      selected_products() {
        var selected_products = 0
        for (var i = 0; i < this.goods.length; i++) {
          var product = this.goods[i].list
          for (var j = 0; j < product.length; j++) {
            if (product[j].product_checked) {
              selected_products++
            }
          }
        }
        return selected_products
      },

      // 购买商品总金额
      total_amount() {
        var total_price = 0.00
        for (var i = 0; i < this.goods.length; i++) {
          var product = this.goods[i].list
          for (var j = 0; j < product.length; j++)
            if (product[j].product_checked) {
              total_price += product[j].number * product[j].current_price
            }
        }
        return total_price
      },

      // 购物车全选
      all_checked() {
        for (var i = 0; i < this.goods.length; i++) {
          if (!this.goods[i].all_checked) {
            return false
          }
        }
        return true
      }
    }
  }

样式:

<style scoped>

  .car_main {
    position: relative;
    width: 980px;
    margin: 0px auto;
    padding: 0px 0px;
    min-height: 250px;
  }

  .car_head {
    width: 100%;
    height: 45px;
    line-height: 45px;
    color: #3c3c3c;
    font-size: 14px;
    padding: 0px;
    border-bottom: 1px solid #DCDCDC;
  }

  .car_top {
    width: 100%;
    height: 50px;
  }

  ul {
    list-style: none;
  }

  li {
    float: left;
    text-align: left;
  }

  .car_check_all {
    position: relative;
    width: 10%;
    left: -20px;
  }

  .car_check_all input[type="checkbox"] {
  }

  .car_check_all label {
  }

  .car_information {
    width: 45%;
  }

  .car_price {
    width: 11%;
  }

  .car_number {
    width: 10%;
  }

  .car_amount {
    width: 11%;
  }

  .cart_empty {
    position: absolute;
    width: 100%;
    top: 50%;
    text-align: center;
  }

  .car_foot_bar {
    position: absolute;
    width: 100%;
    height: 45px;
    font-size: 14px;
    color: #3c3c3c;
    margin-top: 15px;
  }

  .car_foot_settle {
    float: right;

  }

  .piece {
    float: left;
    height: 45px;
    line-height: 45px;
  }

  .totalMoney {
    float: left;
    margin-left: 20px;
    height: 45px;
    line-height: 45px;
  }

  .settle_accounts {
    float: left;
    margin-left: 20px;
    height: 45px;
    line-height: 45px;
  }

  .piece_num {
    color: red;
  }

  .total_text {
    color: red;
    font-size: 18px;
  }

  .settle_button {
    width: 100px;
    height: 45px;
    line-height: 45px;
    border: none;
    outline: none;
    background-color: red;

  }

  .settle_button:disabled {
    background-color: #eeefff;
  }

  .shop_info {
    width: 100%;
    height: 20px;
    margin-top: 20px;
    margin-bottom: 10px;
    font-size: 12px;
    align-items: center;
    display: flex;
  }

  .shop_info_check_all {
    position: relative;
    width: 10px;
    left: -20px;
  }

  .shop_info li a {
    text-decoration: none;
    margin-right: 10px;
    color: #3c3c3c;
  }

  .shop_info li a:hover {
    color: red;
    text-decoration: underline;
  }

  .shop_icon {
    width: 16px;
    height: 16px;
  }

  .shop_discount {
    width: 60px;
    height: 20px;
    margin-left: 10px;
  }

  .product {
    width: 100%;
    border: 1px solid #DCDCDC;
    background: #F5F5F5;
  }

  .selected_styles {
    background: lightgoldenrodyellow;
  }

  .product_details {
    width: 100%;
    height: 145px;
    padding-left: 20px;
  }

  .product_description {
    width: 100%;
    height: 25px;
    background: white;
    font-size: 12px;
    padding-left: 50px;
    align-items: center;
    display: flex;
  }

  .product_description_bg {
    width: fit-content;
    background: #eee;
    height: 20px;
    line-height: 20px;
  }

  .product_check {
    float: left;
    margin-top: -8px;
    padding-top: 20px;
  }

  .product_img {
    float: left;
    padding-top: 20px;
  }

  .product_shop_info {
    height: 100px;
    float: left;
    padding-left: 10px;
    position: relative;
    width: 220px;
    padding-right: 20px;
    padding-top: 20px;
  }

  .product_shop_name {
    font-size: 12px;
    text-align: left;
  }

  .product_shop_name a {
    text-decoration: none;
    letter-spacing: 2px;
    color: #3c3c3c;
    align-content: left;
  }

  .product_shop_name a:hover {
    color: red;
    text-decoration: underline;
  }

  .product_shop_icon {
    position: absolute;
    bottom: 0px;
    width: fit-content;
  }

  .product_type_select {
    width: 155px;
    height: 120px;
    font-size: 12px;
    text-align: left;
    float: left;
    position: relative;
    padding-bottom: 10px;
    color: #3c3c3c;
    border: 1px dashed transparent;
  }

  .product_type_select:hover {
    border: 1px dashed #F00
  }

  .product_type_all:first-child {
    padding-top: 20px;
  }

  .product_type {
    width: 125px;
    margin-bottom: 10px;
    margin-left: 15px;
  }

  .product_edit {
    width: fit-content;
    position: absolute;
    top: 0;
    right: 0;
  }

  .product_edit_button {
    color: white;
    background: red;
    border: none;
    outline: none;
  }

  .product_edit_type_true {
    display: block;
  }

  .product_edit_type_false {
    display: none;
  }

  .product_price {
    width: 105px;
    float: left;
    padding-top: 20px;
    text-align: left;
    padding-left: 20px;
  }

  .product_price_origin {
    width: fit-content;
    font-size: 14px;
    color: grey;
    text-decoration: line-through;
  }

  .product_price_current {
    width: fit-content;
    font-size: 14px;
    font-weight: bold;
  }

  .product_number {
    width: 90px;
    float: left;
    padding-top: 20px;
  }

  .product_number_content {
    width: fit-content;
    height: 24px;
    background: #eee;
  }

  .product_number_button {
    width: 24px;
    float: left;
    margin: 0px auto;
    border: 1px solid transparent;
  }

  .product_number_button button {
    width: 24px;
    height: 24px;
    outline: none;
    background: transparent;
    border: 1px solid transparent;
  }

  .product_number_button button:hover {
    background: transparent;
    border: 1px solid orange;
  }

  .product_number_input {
    width: fit-content;
    text-align: center;
    float: left;
    margin: 0px auto;
  }

  .product_number_input input {
    width: 30px;
    height: 24px;
    text-align: center;
    box-sizing: border-box;
  }

  .product_number_input input::-webkit-inner-spin-button {
    -webkit-appearance: none;
  }

  .product_number_input input::-webkit-outer-spin-button {
    -webkit-appearance: none;
  }

  .product_amount {
    width: 100px;
    float: left;
    padding-top: 20px;
  }

  .product_total_price {
    width: 100px;
    font-size: 16px;
    color: red;
    font-weight: bold;
    word-wrap: break-word;
  }

  .product_operation {
    width: 100px;
    float: left;
    padding-top: 20px;
    text-align: left;
    margin-left: 20px;
    line-height: 15px;
    color: #3c3c3c;
  }

  .product_operation button {
    width: fit-content;
    border: none;
    background: transparent;
    outline: none;
    font-size: 12px;
  }

  .product_operation button:hover {
    color: red;
    text-decoration: underline;
  }
</style>

猜你喜欢

转载自blog.csdn.net/qingyulove/article/details/81351129
今日推荐