前端实现购物车功能

<template>
  <div class="car">
    <p class="car_title">我的购物车</p>
    <el-table
      style="width: 80%; margin: auto"
      :header-cell-style="{
        background: '#E7ECFC',
        color: 'rgb(78 71 71)',
        'font-weight': 'bold',
        'text-align': 'center',
        padding: '7px 0px',
      }"
      :cell-style="{ padding: '7px 0px', 'text-align': 'center' }"
      ref="multipleTable"
      :data="state.products"
      tooltip-effect="dark"
      @selection-change="handleSelectionChange"
      @select="select"
      show-summary
      :summary-method="getSummaries"
    >
      <el-table-column type="selection" width="100px"></el-table-column>
      <el-table-column label="商品" width="200px" prop="name">
        <template #default="scope">
          <div class="product">
            <el-image
              style="width: 100px"
              :src="scope.row.cover_img ? scope.row.cover_img : ''"
              fit="scale-down"
            />
            <span class="title">{{ scope.row.name }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="price" label="单价">
        <template #default="scope">
          <span>¥{{ scope.row.price }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="number" width="200px" label="购买数量">
        <template #default="scope">
          <el-input-number
            v-model="scope.row.number"
            :min="1"
            :max="scope.row.stock"
            @change="handleChange(scope.$index, scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="number" label="小计">
        <template #default="scope">
          <span>¥{{ scope.row.number * scope.row.price }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="address" label="操作">
        <template #default="scope">
          <span class="btn" @click="deleteGoods(scope.$index, scope.row)"
            >删除</span
          >
          <span class="btn" @click="cutPrice(scope.$index, scope.row)"
            >砍价</span
          >
        </template>
      </el-table-column>
      <el-table-column prop="address" label="期望单价" v-if="state.show">
        <template #default="scope">
          <!-- <el-input v-if="state.current===scope.$index" v-model="scope.row.bargain_price"></el-input> -->
          <el-input v-model="scope.row.bargain_price"></el-input>
        </template>
      </el-table-column>
    </el-table>
    <!-- <h3 class="total">
      总价:¥{{ allPrice }}
      <span v-show="allPrice2">砍价后 ¥{{ allPrice2 }}</span>
    </h3> -->
    <!-- <p></p> -->
    <p class="submit" type="danger" @click="submit">
      提交&nbsp;&nbsp;&nbsp;<span class="iconfont icon-youjiantou"></span>
    </p>
    <el-pagination v-if="state.total > 0" v-model:current-page="state.page" background layout="total, sizes, prev, pager, next, jumper"
        :page-size="Number(state.limit)" :total="Number(state.total)" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
    <!-- <el-pagination
      background
      class="mt-4"
      v-model:current-page="state.page"
      v-model:page-size="state.limit"
      :page-sizes="[10, 15, 20, 25]"
      layout="total,sizes, prev, pager, next"
      :total="state.total"
      @current-change="handleCurrentChange"
      @size-change=""
    /> -->
  </div>
</template>

<script setup>
import { reactive, computed, watch, onMounted, onBeforeMount } from "vue";
import { getCar, car, order_front, orderList_front } from "@/api/request";
import { ElImage, ElInputNumber, ElMessage, subMenuProps } from "element-plus";
const state = reactive({
  products: [],
  shopCar: [],
  id: "",
  cutPrice: 0,
  show: false,
  page: 1,
  limit: 10,
  total: 0,
  current: -1, //当前所处下标
});
let getSummaries = (param) => {
  const { columns, data } = param;
  const sums = [];
  columns.forEach((column, index) => {
    // 设置第一列想显示的字

    if (index === 0) {
      sums[index] = "合计";
      return;
    }
    console.log("打印item", data);
    const values = data.map((item) => Number(item[column.property]));
    let sum = 0;
    // if (index == 2) {
    //   // sums[index]=allPrice()
    //   sum = 0;
    //   sum = data.reduce((sum, object) => {
    //     return (sum += object.price * 1);
    //   }, 0);

    //   sums[index] = "¥" + sum;
    // } else
    if (index == 3) {
      sum = 0;
      const values = data.map((item) => Number(item["number"]));
      values.forEach((item) => {
        sum = sum + item;
      });
      sums[index] = sum;
    } else if (index == 4) {
      sum = 0;
      sum = data.reduce((sum, object) => {
        
        return (sum += object.price * object.number);
      }, 0);
      sums[index] = "¥" + sum;
    } else if (index == 6) {
      sum = 0;
      sum = data.reduce((sum, object) => {
        return (sum += object.bargain_price * object.number);
      }, 0);
      sums[index] = "¥" + sum;
    }
    // if (index != 3) {
    //   // 想自定义求平均数的列
    //   // Number.isNaN(value)) 判断value是否是数值类
    //   if (!values.every((value) => Number.isNaN(value))) {
    //     sums[index] = `${values.reduce((prev, curr) => {
    //       const value = Number(curr);
    //       if (!Number.isNaN(value)) {
    //         return prev + curr;
    //       } else {
    //         return prev;
    //       }
    //     }, 0)}`;
    //   } else {
    //     sums[index] = "-";
    //   }
    // } else {

    //   sums[index] = sum / values.length;
    // }
  });
  return sums;
};

onBeforeMount(() => {
  getList();
});
const getList = () => {
  let obj = {
    page: state.page,
    limit: state.limit,
  };
  getCar(obj).then((res) => {
    console.log("🚀 ~ file: car.vue:77 ~ getCar ~ res:", res);
    state.total = res.data.total;
    state.products = res.data.data;
    state.products=state.products.map(x=>{
        x.bargain_price=x.price
        return x
    })
    console.log("获取数组", state.products);
    console.log(
      "🚀 ~ file: car.vue:89 ~ getCar ~ state.products:",
      state.products
    );
  });
};

const allPrice = computed(() => {
  return state.shopCar.reduce((sum, object) => {
    return (sum += object.price * object.number);
  }, 0);
});
const allPrice2 = computed(() => {
  return state.shopCar.reduce((sum, object) => {
    return (sum += object.bargain_price * object.number);
  }, 0);
});
watch(
  state.products,
  (newValue, oldValue) => {
    console.log("sum变了", newValue);
    state.products = newValue;
  },
  {
    immediate: true,
    deep: true,
  }
);
const handleCurrentChange = (val) => {
  state.page = val;
  getList()
};
const handleSizeChange = (val) => {
  state.limit= val;
  getList()
};
const handleSelectionChange = (selection) => {
  state.shopCar = selection;
  console.log(
    "🚀 ~ file: car.vue:103 ~ handleSelectionChange ~ state.shopCar:",
    state.shopCar
  );
};
//删除商品
const deleteGoods = (index, row) => {
  state.products.splice(index, 1);
  let obj = {
    id: [row.id],
  };
  car(obj, "delete").then((res) => {
    if (res.code == 200) {
      ElMessage.success("删除购物车成功!");
      getList();
    }
  });
  //删除
};
//砍价
const cutPrice = (index, row) => {
  console.log(index, row);
  state.show = true;
  state.current = index;
};
// 复选框
const select = (selection) => {
  state.shopCar = selection;
  console.log(
    "🚀 ~ file: car.vue:117 ~ select ~ state.shopCar:",
    state.shopCar
  );
  console.log(state.shopCar);
};
const handleChange = (index, row) => {
  console.log(index, row);
  if (state.shopCar[index]) {
    state.shopCar[index].number = row.number;
  }
};
const submit = () => {
  console.log("submit");
  if (state.shopCar.length == 0) {
    ElMessage({
      type: "warning",
      message: "请选择商品",
    });
    return false;
  }
  let obj = {
    interface: 2,
    list: state.shopCar,
  };
  // console.log("list",state.shopCar);

  order_front(obj, "post").then((res) => {
    ElMessage.success("提交成功,等待商家审核");
    // let obj = {
    //   id: [row.id],
    // };
    let ids = state.shopCar.map((x) => x.id);
    car({ id: ids }, "delete").then((res) => {
      if (res.code == 200) {
        getList();
      }
    });
  });
};
</script>

<style lang="scss" scoped>
.submit {
  position: fixed;
  right: 0;
  top: 35%;
  background-color: #a0afe0;
  color: #fff;
  width: 100px;
  border-radius: 30px 0 0 30px;
  text-align: center;
  line-height: 50px;
  cursor: pointer;
  z-index: 999;
}

.submit:hover {
  background-color: #6c84d3;
}

.total,
.el-pagination {
  padding: 10px 5%;
}

.product {
  display: flex;
  align-items: center;
  justify-content: center;
}

.title {
  padding-left: 5px;
  text-align: left;
  width: 100px;
  // color: white;
  font-weight: bold;
}

.car {
  background-color: #fff;
  width: 100%;
  height: 100%;
  // color: white;

  &_title {
    // color: white;
    font-weight: bold;
    font-size: 20px;
    padding-top: 20px;
    margin-left: 60px;
    margin-bottom: 20px;
    box-sizing: border-box;
  }
}

.btn {
  color: #c67b82;
  font-weight: bold;
  width: 40px;
  display: inline-block;
  cursor: pointer;
  // color: #FF5157;
}
</style>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值