Vue小项目(开发一个购物车)
基于Vue知识点1(点击跳转)、Vue知识点2(点击跳转)
想要学习更多前端知识:点击Web前端专栏
接下来我们开发一个如下图所示,有最基本购物车功能的简易小项目
下面这是最基本的HTML+CSS框架!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实战小项目:购物车</title>
<style>
body {
font-family: Arial, sans-serif;
}
.cart-item {
width: 50%;
margin-bottom: 15px;
padding: 10px;
border: 2px solid gray;
border-radius: 10px;
background-color: #ddd;
}
.buttons {
margin-top: 5px;
}
.buttons button {
padding: 5px 10px;
margin-right: 5px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 3px;
background-color: pink;
}
.buttons input {
width: 25px;
}
.buttons button:hover {
background-color: yellow;
}
.quantity {
font-size: 18px;
font-weight: bold;
margin-left: 10px;
}
h1, h2 {
color: #333;
}
</style>
</head>
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item">
<div class="buttons">
<span>苹果 </span>
<button>-</button>
<span class="quantity">1 </span>
<button>+</button>
<p>
请输入价格:
<input type="text"/> 元/斤 <br>
单价:
1 元/斤
</p>
</div>
</div>
<!-- 提示:可以用计算属性或数据变动侦听器,跟踪商品数和单价的变化,进而求出总数和总价-->
<h3>商品总数: <ins> 1 </ins> 件</h3>
<h3>商品总价: <ins> 1 </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
// 2.定义方法:增加商品数
// 3.定义方法:减少商品数
// 4.定义方法:计算商品总数
// 5.定义方法:计算商品总价
// 6.暴露属性和方法
}
}).mount('#app');
</script>
</body>
</html>
这时候还没有实现任何交互性的网页应用,单纯是一个静态网页,接下来看看怎么运用Vue来实现数据与视图的双向绑定,将其变成一个实用的小项目吧!
1、实现增加商品品类
首先我们可以先定义一个 cartItems 属性,是用来存储商品的一个(响应式)数组;再通过v-for指令遍历这个数组(假设有n个品类,则生成n个商品项);并使用 {{item.name}} 插值表达式将每个商品名称渲染出来
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item" v-for="(item, index) in cartItems">
<div class="buttons">
<span>{{item.name}} </span>
<button>-</button>
<span class="quantity">1 </span>
<button>+</button>
<p>
请输入价格:
<input type="text"/> 元/斤 <br>
单价:
1 元/斤
</p>
</div>
</div>
<h3>商品总数: <ins> 1 </ins> 件</h3>
<h3>商品总价: <ins> 1 </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
const cartItems = reactive([
{ name: '苹果', quantity: 1, unit_price: 1 },
{ name: '香蕉', quantity: 1, unit_price: 1 },
{ name: '菠萝', quantity: 1, unit_price: 1 },
// 可以自适应添加更多商品
// { name: '芒果', quantity: 1, unit_price: 1 },
// { name: '鸭梨', quantity: 1, unit_price: 1 },
]);
// 暴露属性和方法
return{
cartItems,
}
}
}).mount('#app');
</script>
</body>
这样商品品类有多少就会自动更新啦!
2、实现商品数增加
我们可以定义一个方法 increaseQuantity 用来增加商品数,并将这个方法绑定到 click 事件上,当这个按钮被点击时就会调用这个方法;因为按钮并不是同一个按钮,我们需要用到数组 v-for 遍历出来的 index 索引来区分每一个商品的商品数和单价,并且使用{{ }} 插值表达式将它们渲染出来
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item" v-for="(item, index) in cartItems">
<div class="buttons">
<span>{{item.name}} </span>
<button>-</button>
<span class="quantity">{{ cartItems[index].quantity }} </span>
<!-- 使用v-on指令,调用方法时需要用到括弧,并传入index参数 -->
<button v-on:click="increaseQuantity(index)">+</button>
<p>
请输入价格:
<input type="text"/> 元/斤 <br>
单价:
{{cartItems[index].unit_price}} 元/斤
</p>
</div>
</div>
<h3>商品总数: <ins> 1 </ins> 件</h3>
<h3>商品总价: <ins> 1 </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
const cartItems = reactive([
{ name: '苹果', quantity: 1, unit_price: 1 },
{ name: '香蕉', quantity: 1, unit_price: 1 },
{ name: '菠萝', quantity: 1, unit_price: 1 },
// 可以自适应添加更多商品
// { name: '芒果', quantity: 1, unit_price: 1 },
// { name: '鸭梨', quantity: 1, unit_price: 1 },
]);
// 2.定义方法:增加商品数
const increaseQuantity = (index) => {
cartItems[index].quantity += 1;
}
// 暴露属性和方法
return{
cartItems,
increaseQuantity,
}
}
}).mount('#app');
</script>
</body>
这样增加商品的按钮就做好啦!
3、 实现商品数减少
减少商品数和增加商品数差不多,只是需要注意的是商品不能减少到0,只有商品数大于1的时候才可减少;相同,我们可以定义一个方法 decreaseQuantity 用来减少商品数,并使用v-on指令将这个方法绑定到 click 事件上,当这个按钮被点击时就会调用这个方法
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- -->
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item" v-for="(item, index) in cartItems">
<div class="buttons">
<span>{{item.name}} </span>
<!-- 使用v-on指令,调用方法时需要用到括弧,并传入index参数 -->
<button v-on:click="decreaseQuantity(index)">-</button>
<span class="quantity">{{ cartItems[index].quantity }} </span>
<button v-on:click="increaseQuantity(index)">+</button>
<p>
请输入价格:
<input type="text"/> 元/斤 <br>
单价:
{{cartItems[index].unit_price}} 元/斤
</p>
</div>
</div>
<h3>商品总数: <ins> 1 </ins> 件</h3>
<h3>商品总价: <ins> 1 </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
const cartItems = reactive([
{ name: '苹果', quantity: 1, unit_price: 1 },
{ name: '香蕉', quantity: 1, unit_price: 1 },
{ name: '菠萝', quantity: 1, unit_price: 1 },
// 可以自适应添加更多商品
// { name: '芒果', quantity: 1, unit_price: 1 },
// { name: '鸭梨', quantity: 1, unit_price: 1 },
]);
// 2.定义方法:增加商品数
const increaseQuantity = (index) => {
cartItems[index].quantity += 1;
}
// 3.定义方法:减少商品数
const decreaseQuantity = (index) => {
if(cartItems[index].quantity > 1){ //只有商品数大于1的时候才可减少
cartItems[index].quantity -= 1;
}
}
// 暴露属性和方法
return{
cartItems,
increaseQuantity,
decreaseQuantity,
}
}
}).mount('#app');
</script>
这样减少商品的按钮也做好啦!
4、计算商品总数
计算商品总数可以使用计算属性 computed定义一个方法 totalItems ,然后定义一个储存商品总数的变量,遍历cartItems,取出每个商品数量将其加进变量中,最后返回变量的值;并且使用{{ }} 插值表达式将它们渲染出来(调用计算属性 computed不需要加括弧)
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- -->
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item" v-for="(item, index) in cartItems">
<div class="buttons">
<span>{{item.name}} </span>
<button v-on:click="decreaseQuantity(index)">-</button>
<span class="quantity">{{ cartItems[index].quantity }} </span>
<button v-on:click="increaseQuantity(index)">+</button>
<p>
请输入价格:
<input type="text"/> 元/斤 <br>
单价:
{{cartItems[index].unit_price}} 元/斤
</p>
</div>
</div>
<!-- 提示:可以用计算属性或数据变动侦听器,跟踪商品数和单价的变化,进而求出总数和总价-->
<h3>商品总数: <ins> {{totalItems}} </ins> 件</h3>
<h3>商品总价: <ins> 1 </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
const cartItems = reactive([
{ name: '苹果', quantity: 1, unit_price: 1 },
{ name: '香蕉', quantity: 1, unit_price: 1 },
{ name: '菠萝', quantity: 1, unit_price: 1 },
// 可以自适应添加更多商品
// { name: '芒果', quantity: 1, unit_price: 1 },
// { name: '鸭梨', quantity: 1, unit_price: 1 },
]);
// 2.定义方法:增加商品数
const increaseQuantity = (index) => {
cartItems[index].quantity += 1;
}
// 3.定义方法:减少商品数
const decreaseQuantity = (index) => {
if(cartItems[index].quantity > 1){
cartItems[index].quantity -= 1;
}
}
// 4.定义方法:计算商品总数
const totalItems = computed(() =>
{
let total_items = 0; //定义一个储存商品总数的变量
for(const item of cartItems){ //遍历cartItems,取出每个商品
total_items += item.quantity; //将商品数量加进total_items
}
return total_items //返回变量的值
}
)
// 暴露属性和方法
return{
cartItems,
increaseQuantity,
decreaseQuantity,
totalItems,
}
}
}).mount('#app');
</script>
</body>
这样商品总数就能计算出来啦!
5、计算商品总价
计算商品总价一样可以使用计算属性 computed定义一个方法 totalMoney,然后定义一个储存商品总价的变量,遍历cartItems,取出的每个商品数量乘上每个商品单价将其加进变量中,最后返回变量的值;再使用v-model指令使每个价格的文本输入框与其单价数据双向绑定,并且使用{{ }} 插值表达式将它们渲染出来(调用计算属性 computed不需要加括弧)
<body>
<div id="app">
<h1>实战小项目:购物车</h1>
<!-- -->
<!-- 提示:可以使用v-for指令,假设有n个品类,则生成n个商品项-->
<div class="cart-item" v-for="(item, index) in cartItems">
<div class="buttons">
<span>{{item.name}} </span>
<button v-on:click="decreaseQuantity(index)">-</button>
<span class="quantity">{{ cartItems[index].quantity }} </span>
<button v-on:click="increaseQuantity(index)">+</button>
<p>
请输入价格:
<!-- 使用v-model指令使其双向数据绑定 -->
<input type="text" v-model="cartItems[index].unit_price"> 元/斤 <br>
单价:
{{cartItems[index].unit_price}} 元/斤
</p>
</div>
</div>
<!-- 提示:可以用计算属性或数据变动侦听器,跟踪商品数和单价的变化,进而求出总数和总价-->
<h3>商品总数: <ins> {{totalItems}} </ins> 件</h3>
<h3>商品总价: <ins> {{totalMoney}} </ins> 元</h3>
</div>
<script type="module">
import { createApp, reactive, computed } from './vue.esm-browser.js'
createApp({
setup() {
// 1.定义属性:存储商品的(响应式)数组
const cartItems = reactive([
{ name: '苹果', quantity: 1, unit_price: 1 },
{ name: '香蕉', quantity: 1, unit_price: 1 },
{ name: '菠萝', quantity: 1, unit_price: 1 },
// 可以自适应添加更多商品
// { name: '芒果', quantity: 1, unit_price: 1 },
// { name: '鸭梨', quantity: 1, unit_price: 1 },
]);
// 2.定义方法:增加商品数
const increaseQuantity = (index) => {
cartItems[index].quantity += 1;
}
// 3.定义方法:减少商品数
const decreaseQuantity = (index) => {
if(cartItems[index].quantity > 1){
cartItems[index].quantity -= 1;
}
}
// 4.定义方法:计算商品总数
const totalItems = computed(() =>
{
let total_items = 0;
for(const item of cartItems){
total_items += item.quantity;
}
return total_items
}
)
// 5.定义方法:计算商品总价
const totalMoney = computed(()=>
{
let total_money = 0; //定义一个储存商品总数的变量
for(const money of cartItems){ //遍历cartItems,取出每个商品
total_money += money.unit_price*money.quantity; //将每个商品数量乘上每个商品单价再加进变量total_money
}
return total_money //返回变量的值
})
// 暴露属性和方法
return{
cartItems,
increaseQuantity,
decreaseQuantity,
totalItems,
totalMoney
}
}
}).mount('#app');
</script>
</body>
这样一个简单的购物车小项目就做好啦!