vue+vant构建购物车单选多选以及结算功能

设置全局相应拦截和全局请求拦截

import axios from "axios"; //npm i axios后引用
import { getToken } from "../utils/auth.js"; //这边为封装的获取token的封装函数:export function getToken() {return localStorage.getItem("token");}

const service = axios.create({
  baseURL: "http://192.168.18.71:3009/",
  timeout: 5000,
});

//全局请求拦截
service.interceptors.request.use(
  (config) => {
    config.headers["authorization"] = "Bearer " + getToken();
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

//全局响应拦截
service.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    if (error.response && error.response.status === 401) {
      window.location.href = "#/login";
    }
    return Promise.reject(error);
  }
);

// export const get = (url, params) => service.get(url, { params });
export function get(url, params) {
  return service.get(url, { params });
}
export const post = (url, data) => service.post(url, data);
export const put = (url, data) => service.put(url, data);
export const del = (url, data) => service.delete(url, data);

export default service;

购物车的功能(结算,单选,反选,以及加减,这里我使用了自己的接口,按照要求改成自己的接口获取数据即可)

<template>
  <div class="shopCart">
    <!-- <cartNav></cartNav> -->
    <div class="cartList">
      <ul v-if="goods.length > 0">
        <li v-for="item in goods" :key="item.product._id">
          <van-checkbox
            :value="item.id"
            v-model="item.isChecked"
            checked-color="#15C481"
            @click="chooseChange(item.product._id, item)"
          ></van-checkbox>
          <div class="shopdetail">
            <div class="detailimg">
              <!-- 判断是否有图片 -->
              <img
                :src="item.product.coverImg!=null?'http://localhost:3009/'+item.product.coverImg
                :'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3055768216,2672833891&fm=11&gp=0.jpg'"
              />
            </div>
            <div class="detailtext">
              <div class="shoptitle van-multi-ellipsis--l2">{{ item.product.name }}</div>
              <div class="shoppricenum">
                <p class="shopprice">
                  ¥{{ item.product.price
                  }}
                </p>
                <div class="shopnum">
                  <van-stepper v-model="item.num" @change="onChange(item)" />
                </div>
              </div>
            </div>
          </div>
        </li>
      </ul>
      <div class="nohaveshop" v-else>
        <van-icon name="shopping-cart-o" />
        <p class="p1">你的购物车空空如也~~</p>
        <p class="p2">快去采购吧!</p>
      </div>
    </div>
    <div class="cartfotter" v-if="goods.length > 0">
      <van-submit-bar button-text="去结算" @submit="onSubmit">
        <van-checkbox v-model="allchecked" checked-color="#15C481" @click="checkAll">全选</van-checkbox>
        <div class="buyprice">
          <p class="p1">合计</p>
          <p class="p2">¥{{ totalprice }}</p>
        </div>
      </van-submit-bar>
    </div>
  </div>
</template>

<script>
import { Icon, Checkbox, Stepper, SubmitBar, Toast } from "vant";
import cartNav from "../components/cartNav.vue";
import {get} from "../utils/request";
export default {
  components: {
    [Icon.name]: Icon,
    [Checkbox.name]: Checkbox,
    [Stepper.name]: Stepper,
    [SubmitBar.name]: SubmitBar,
    [Toast.name]: Toast,
    //cartNav
  },
  data() {
    return {
      goods: [],
      allchecked: false,
      selectedData: [],
      // 总价
      totalprice: 0
    };
  },
  created: async function() {
    this.count();
  },
  async created() {
    //获取商品数据
    const result = await get("/api/v1/shop_carts");
    console.log(result.data);
    this.goods = result.data.filter(i => i.product);
  },
  computed: {},
  methods: {
    // 单选的change事件
    chooseChange(i, item) {
      Toast("选中后输入文字会弹出文字");
      if (this.selectedData.indexOf(i) > -1) {
        console.log(i);
        var arrs = this.selectedData.filter(function(item) {
          return item != i;
        });
        this.selectedData = arrs;
        item.isChecked = false;
        // this.remove(this.selectedData, i);
        this.count();
        console.log(this.selectedData);
      } else {
        this.selectedData.push(i);
        item.isChecked = true;
        this.count();
      }
      if (this.selectedData.length < this.goods.length) {
        this.allchecked = false;
      } else {
        this.allchecked = true;
      }
      this.count();
      console.log(this.selectedData);
    },
    // 商品数量
    onChange(item) {
      Toast(item.num);
      this.count();
      console.log(this.goods);
    },
    // 计算价格
    count: function() {
      var totalPrice = 0; //临时总价
      var totalLvd = 0; //临时lvd
      this.goods.forEach(function(val) {
        if (val.isChecked) {
          totalPrice += val.quantity * val.product.price; //累计总价
        }
      });
      this.totalprice = totalPrice;
    },
    // 全选
    checkAll() {
      let list = this.goods;
      if (this.allchecked === true) {
        list.forEach(element => {
          element.isChecked = true;
        });
        this.selectedData = [];
        this.count();
        console.log("111" + this.selectedData);
      } else {
        list.forEach(element => {
          element.isChecked = false;
          if (this.selectedData.indexOf(element.id) < 0) {
            this.selectedData.push(element.id);
          }
        });
        this.count();
        console.log("222" + this.selectedData);
      }
    },
    // 去结算
    onSubmit() {
      // 选择购买的商品
      var cartgoods = [];
      this.goods.forEach(function(item) {
        if (item.isChecked) {
          cartgoods.push({ id: item.id, num: item.num });
        }
      });
      if (cartgoods.length === 0) {
        Toast("请选择商品购买");
      } else {
        this.$router.push("shopBuy");
      }
      console.log(cartgoods);
    }
  }
};
</script>

<style lang="scss" scoped>
.shopCart {
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f6f6f6;
  .cartList {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: 16px;
    ul {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      margin-bottom: 100px;
      li {
        width: 100%;
        height: 96px;
        background-color: #fff;
        display: flex;
        flex-direction: row;
        align-items: center;
        margin-bottom: 12px;
        .van-checkbox {
          margin-left: 17px;
          ::v-deep .van-checkbox__icon {
            height: 14px;
            line-height: 14px;
            .van-icon {
              width: 14px;
              height: 14px;
              font-size: 12px;
              border: 1px solid #a5a5a5;
            }
          }
        }
        .shopdetail {
          display: flex;
          flex-direction: row;
          align-items: center;
          margin-left: 13px;
          .detailimg {
            width: 64px;
            height: 64px;
            background: rgba(165, 165, 165, 1);
            border-radius: 4px;
            img {
              width: 100%;
              height: 100%;
              border-radius: 4px;
            }
          }
          .detailtext {
            width: 230px;
            height: 60px;
            display: flex;
            flex-direction: column;
            margin-left: 8px;
            position: relative;
            .shoptitle {
              width: 180px;
              text-align: justify;
              font-size: 12px;
              color: #212121;
              line-height: 17px;
            }
            .shoppricenum {
              width: 100%;
              display: flex;
              flex-direction: row;
              align-items: center;
              justify-content: space-between;
              position: absolute;
              bottom: 0px;
              .shopprice {
                font-size: 12px;
                color: #15c481;
                font-weight: 600;
              }
              .shopnum {
                display: flex;
                ::v-deep .van-stepper {
                  button {
                    width: 14px;
                    height: 14px;
                    border: 1px solid #333333;
                    border-radius: 50px;
                    background-color: #fff;
                  }
                  .van-stepper__minus::before {
                    width: 8px;
                  }
                  .van-stepper__plus::before {
                    width: 8px;
                  }
                  .van-stepper__plus::after {
                    height: 8px;
                  }
                  .van-stepper__input {
                    font-size: 12px;
                    color: #333333;
                    background-color: #fff;
                    padding: 0px 12px;
                  }
                }
              }
            }
          }
        }
      }
    }
    .nohaveshop {
      display: flex;
      flex-direction: column;
      align-items: center;
      margin-top: 100px;
      .van-icon {
        font-size: 60px;
        color: #666;
      }
      p {
        font-size: 14px;
        color: #999;
      }
      .p1 {
        margin-top: 20px;
      }
    }
  }
  .cartfotter {
    width: 100%;
    height: 60px;
    position: fixed;
    bottom: 0;
    left: 0;
    .van-submit-bar__bar {
      height: 60px;
      font-size: 16px;
      .van-checkbox {
        margin-left: 17px;
        ::v-deep .van-checkbox__icon {
          height: 14px;
          line-height: 14px;
          .van-icon {
            width: 14px;
            height: 14px;
            font-size: 12px;
            border: 1px solid #a5a5a5;
          }
        }
        ::v-deep .van-checkbox__label {
          font-size: 16px;
          color: #212121;
          margin-left: 9px;
        }
      }
      .buyprice {
        flex: 1;
        padding-right: 8px;
        text-align: right;
        display: flex;
        flex-direction: column;
        .p1 {
          font-size: 10px;
          color: #001410;
        }
        .p2 {
          font-size: 12px;
          color: #15c481;
          margin-top: 4px;
        }
      }
      .van-button--danger {
        width: 130px;
        height: 60px;
        background: rgba(21, 196, 129, 1);
        border: none;
        font-size: 16px;
        color: #ffffff;
      }
    }
  }
}
</style>
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值