- 收货人:{{ curAddress.userName }}
- 联系方式:{{ curAddress.phone }}
- 收货地址: {{ curAddress.address }}
创建cartStore.js文件, 将购物车列表数据存在pinia中
import { ref, computed } from "vue";
import { defineStore } from "pinia";
import { useUserStore } from "./user";
import {
insertCartAPI,
findNewCartListAPI,
delCartAPI,
} from "@/api/cart/index";
export const useCartStore = defineStore(
"cart",
() => {
const userStore = useUserStore();
const isLogin = computed(() => userStore.userInfo.token);
console.log("已经执行登录验证");
//1.定义state - cartList
const cartList = ref([]);
// 2. 定义action - addCart
const addCart = async (goods) => {
console.log(goods);
const { id, count } = goods;
if (isLogin.value) {
// 登录之后的加入购车逻辑
await insertCartAPI({ id, count });
const res = await findNewCartListAPI();
cartList.value = res.data;
console.log("cartList已经赋值");
} else {
console.log("cartList没有赋值");
// 添加购物车操作
// 已添加过 - count + 1
// 没有添加过 - 直接push
// 思路:通过匹配传递过来的商品对象中的id能不能在cartList中找到,找到了就是添加过
const item = cartList.value.find((item) => goods.id === item.goodsId);
console.log("item=" + item);
if (item) {
// 找到了
item.buyCount++;
} else {
console.log("这里运行了");
// 没找到
cartList.value.push(goods);
}
}
};
// 删除购物车
const delCart = async (goodsId) => {
if (isLogin.value) {
// 调用接口实现接口购物车中的删除功能
await delCartAPI([goodsId]);
const res = await findNewCartListAPI();
cartList.value = res.data;
} else {
console.log("cartdel操作已执行");
// 思路:
// 1. 找到要删除项的下标值 - splice
// 2. 使用数组的过滤方法 - filter
const idx = cartList.value.findIndex(
(item) => goodsId === item.goodsId
);
cartList.value.splice(idx, 1);
}
};
//更新购物车
const updateNewList = async () => {
const res = await findNewCartListAPI();
cartList.value = res.data;
console.log("已更新购物车")
};
//清除购物车
const clearCart = () => {
cartList.value = [];
};
// 计算属性
// 1. 总的数量 所有项的count之和
const allCount = computed(() =>
cartList.value.reduce((a, c) => a + c.buyCount, 0)
);
// 2. 总价 所有项的count*price之和
const allPrice = computed(() =>
cartList.value.reduce((a, c) => a + c.buyCount * c.goodsPrice, 0)
);
// 单选功能
const singleCheck = (goodsId, selected) => {
// 通过id找到要修改的那一项 然后把它的selected修改为传过来的selected
const item = cartList.value.find((item) => item.goodsId === goodsId);
item.selected = selected;
};
// 全选功能action
const allCheck = (selected) => {
// 把cartList中的每一项的selected都设置为当前的全选框状态
cartList.value.forEach((item) => (item.selected = selected));
};
// 是否全选计算属性
const isAll = computed(() => cartList.value.every((item) => item.selected));
// 3. 已选择数量
const selectedCount = computed(() =>
cartList.value
.filter((item) => item.selected)
.reduce((a, c) => a + c.buyCount, 0)
);
// 4. 已选择商品价钱合计
const selectedPrice = computed(() =>
cartList.value
.filter((item) => item.selected)
.reduce((a, c) => a + c.buyCount * c.goodsPrice, 0)
);
return {
updateNewList,
clearCart,
selectedPrice,
selectedCount,
isAll,
allCheck,
singleCheck,
cartList,
allCount,
allPrice,
addCart,
delCart,
};
},
{
persist: true,
}
);
创建文件
import http from '@/utils/http'
// 加入购物车
export function insertCartAPI ({ id,count}) {
return http({
url: '/cart',
method: 'POST',
data:{
"goodsId":id,
"buyCount":count
},
})
}
//获取最新的购物车列表
export function findNewCartListAPI () {
return http({
url: '/cart',
method: 'GET',
})
}
//获取最新的购物车列表
export function delCartAPI (ids) {
return http({
url: '/cart',
method: 'DELETE',
data:{
"ids":ids
}
})
}
前往商品详情页面 Detail\index.vue绑定事件和事件逻辑
加入购物车
views/Layout/compopnent/HeaderCart.vue
{{ cartStore.allCount }}
{{ i.goodsName }}
¥{{ i.goodsPrice }}
x{{ i.buyCount }}
共 {{ cartStore.allCount }} 件商品
¥ {{ cartStore.allPrice }}
去购物车结算
在views/Layout/compopnent/LayouHeader.vue中注册和使用HeaderCart组件
创建文件
商品信息
单价
数量
小计
操作
singleCheck(i, selected)"
/>
{{ i.goodsName }}
¥{{ i.goodsPrice }}
¥{{ (i.goodsPrice * i.buyCount).toFixed(2) }}
随便逛逛
共 {{ cartStore.allCount }} 件商品,已选择 {{ cartStore.selectedCount }} 件,商品合计:
¥ {{ cartStore.selectedPrice.toFixed(2) }}
下单结算
创建 views/Checkout/index.vue 文件
编写代码
收货地址
您需要先添加收货地址才可提交订单。
-
收货人:{{ curAddress.userName }}
- 联系方式:{{ curAddress.phone }}
-
收货地址:
{{ curAddress.address }}
切换地址
添加地址
商品信息
商品信息
单价
数量
小计
实付
{{ i.goodsName }}
¥{{ i.goodsPrice }}
{{ i.buyCount }}
¥{{ (i.goodsPrice * i.buyCount).toFixed(2) }}
¥{{ (i.goodsPrice * i.buyCount).toFixed(2) }}
金额明细
- 商品件数:
- {{ cartStore.selectedCount }} 件
- 商品总价:
- ¥{{ cartStore.selectedPrice.toFixed(2) }}
- 应付总额:
-
{{ cartStore.selectedPrice.toFixed(2) }}
提交订单
-
收货人:{{ item.userName }}
- 联系方式:{{ item.phone }}
- 收货地址:{{ item.address }}
代码模版
import http from '@/utils/http'
export function getCheckInfoAPI () {
return http({
url: '/order',
method: 'GET',
})
}
export function createOrderAPI (data) {
return http({
url: '/order',
method: 'POST',
data
})
}
export function getOrderAPI (id) {
return http({
url: `/order/${id}`,
method: 'GET',
})
}
routes: [
{
path: '/',
component: Layout,
children: [
...
{
path: "checkout",
component: Checkout
}
]
}
]
调用接口生成订单id, 并且携带id跳转到支付页
调用更新购物车列表接口,更新购物车状态
// 创建订单
const createOrder = async () => {
const res = await createOrderAPI({
goods: cartStore.cartList
.filter((item) => item.selected)
.map((item) => {
return {
id: item.id,
goodsId: item.goodsId,
buyCount: item.buyCount,
goodsPrice: (item.goodsPrice * item.buyCount).toFixed(2),
};
}),
addressId: curAddress.value.id,
amount: cartStore.selectedPrice,
orderId: time.value,
});
console.log("已经运行到这");
const orderId = time.value;
console.log(orderId);
console.log(orderId);
cartStore.updateNewList();
router.push({
path: "/pay",
query: {
id: orderId,
},
});
};
创建文件 views/Pay/index.vue
编写代码
创建文件
// 封装倒计时函数
import { ref,computed, onUnmounted } from "vue"
import dayjs from "dayjs"
export const useCountDown =()=>{
// 响应式数据
const time = ref(0)
let timer = null
// 格式化事件为xx分xx秒
const formatTime = computed(()=>dayjs.unix(time.value).format('mm分ss秒'))
// 开启倒计时的函数
const start =(currentTime)=>{
// 开启倒计时的逻辑
time.value = currentTime
timer = setInterval(() => {
time.value--
}, 1000);
}
// 组件销毁清除定时器
onUnmounted(() => {
timer && clearInterval(timer)
})
return {
formatTime,start
}
}