购物车项目

Sy_ Lv6

接下来将用Pinia提供的全局数据共享功能来制作一个购物车项目。

项目结构:
::: file-tree

  • components
    • CardList.js
    • Products.js
  • js
    • store.js
    • products.json
  • lib
    • axios.js
    • pinia.min.js
    • vue.min.js
    • vueDemi.js
  • index.html
    :::

文件:
:::: code-tabs
@tab index.html

:collapsed-lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./lib/vue.min.js"></script>
<script src="./lib/vueDemi.js"></script>
<script src="./lib/axios.js"></script>
<script src="./components/ProductList.js"></script>
<script src="./lib/pinia.min.js"></script>
<script src="./js/store.js"></script>
<script src="./components/CartList.js"></script>

<title>淘购</title>
</head>
<body>
<div id="app">
<div id="app">
<h1 class="title">淘购</h1>
<div class="container">
<product></product>
<cart></cart>
</div>
</div>
</div>

<script type="module">
const { createApp} = Vue
const { createPinia } = Pinia
const app = Vue.createApp({});
app.use(createPinia())
app.component("product", ProductList)
app.component("cart", CartList)
app.mount('#app');
</script>
</body>
</html>


<style>
/* App.vue styles */
#app {
font-family: Arial, sans-serif;
text-align: center;
}

.title {
font-size: 24px;
margin-bottom: 20px;
}

.container {
display: flex;
justify-content: space-around;
}

/* ProductList styles */
.product-list {
width: 40%;
border: 1px solid #ccc;
padding: 10px;
}

.product-list ul li{
display: flex;
justify-content: space-between;
margin: 5px 0;
padding: 5px;
border: 1px solid #eee;
}

/* CartList styles */
.cart-list {
width: 40%;
border: 1px solid #ccc;
padding: 10px;
}
.cart-list ul li{
display: flex;
justify-content: space-between;
margin: 5px 0;
padding: 5px;
border: 1px solid #eee;
}
.cart-item span,.hero-item span{
width: 80px;
text-align: center;
}
.total {
font-size: 18px;
margin-top: 10px;
}

</style>

@tab CardList.js

:collapsed-lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const CartList = {
template: `
<div class="cart-list">
<h2>我的购物车</h2>
<ul>
<li>
<span>商品名称</span>
<span>单价</span>
<span>数量</span>
<span>操作</span>
</li>
<li class="cart-item" v-for="cart in store.cart" :key="cart.id">
<span>{{cart.name}}</span>
<span>{{cart.price}}</span>
<span>{{cart.count}}</span>
<button @click="store.removeFromCart(cart)">移除</button>
</li>
</ul>
<p class="total">商品总价:{{store.cart.reduce((sum, item) => sum+item.count*item.price, 0)}} 元 </p>
</div>
`,
setup() {
const store = useProductStore();
return {store}
},
};

@tab store.js

:collapsed-lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const { defineStore } = Pinia

const useProductStore = defineStore("product", {
state: () =>( {
products: [],
cart: []
}),
getters: {
total() {

}
},
actions: {
addToCart(param) {
let thisProduct = this.products.find(item => item.id == param.id)
thisProduct.inventory--;
let CartItem = this.cart.find(item => item.id == param.id)
if (CartItem) {
CartItem.count++;
} else {
this.cart.push({
id: param.id,
name: param.name,
price: param.price,
count: 1,
})
}
},
removeFromCart(param) {
this.cart.forEach((item, i) => {
if (item.id == param.id) {
let product = this.products.find(item => item.id == param.id)
product.inventory++;
if (item.count > 1) {
item.count--;
} else {
this.cart.splice(i, 1)
}
}
});
}
},
})

@tab ProductList.js

:collapsed-lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const {onMounted} = Vue
const ProductList = {
template: `
<div class="product-list">
<h2>商品列表</h2>
<ul>
<li>
<span>商品名称</span>
<span>单价</span>
<span>库存</span>
<span>操作</span>
</li>
<li class="product-item" v-for="product in store.products" :key="product.id">
<span>{{product.name}}</span>
<span>{{product.price}}</span>
<span>{{product.inventory}}</span>
<button @click="store.addToCart(product)" :disabled="!product.inventory">
{{product.inventory?'加入购物车':'库存不足'}}
</button>
</li>
</ul>
</div>
`,
setup() {
const store = useProductStore();
onMounted(() => {
axios("./js/products.json").then(res => {
store.products = res.data;
})
})
return {store}
},
};

@tab products.json

1
2
3
4
5
6
[
{ "id": 1, "name": "书包", "price": 200, "inventory": 5 },
{ "id": 2, "name": "水杯", "price": 100, "inventory": 6 },
{ "id": 3, "name": "电脑", "price": 7000, "inventory": 2 },
{ "id": 4, "name": "鼠标", "price": 150, "inventory": 0 }
]

::::

lib中所包含的库文件CDN:
:::: code-tabs
@tab axios.js

1
https://ccccooh.oss-cn-hangzhou.aliyuncs.com/img/axios.js

@tab pinia.min.js

1
https://ccccooh.oss-cn-hangzhou.aliyuncs.com/img/pinia.min.js

@tab vue.min.js

1
https://ccccooh.oss-cn-hangzhou.aliyuncs.com/img/vue.min.js

@tab vueDemi.js

1
https://ccccooh.oss-cn-hangzhou.aliyuncs.com/img/vueDemi.js

::::

由于托管于我的aliyun OSS,随时可能失效。

  • 标题: 购物车项目
  • 作者: Sy_
  • 创建于 : 2025-06-15 00:51:35
  • 更新于 : 2025-06-15 00:51:35
  • 链接: https://shenying.online//demo/xmld3lww/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
购物车项目