今天通过一个购物车的案例简单阐述一下vue的计算属性,在vue中我们往往需要对数据进行操作后再返回,通常我们需要写一个相关的操作函数来对这些数据进行操作,不过现在vue给这样的数据处理提供了新思路——计算属性。在本例中总价的数据就是利用了该属性。
1.先做一个简单的购物车界面,出来大概是这个样子:
把代码贴下边
<template>
<div class="home">
<Head v-bind:hname="head_name" />
<div class="car_head">
<h2>商品图片</h2>
<h2>商品详情</h2>
<h2>商品单价</h2>
<h2>购买数量</h2>
<h2>单品总价</h2>
</div>
<div class="car" v-for="(item,index) of products" :key="index">
<div class="p_img">

<p>{{item.p_name}}</p>
</div>
<div class="pdetail">
<p>{{item.p_detail}}</p>
</div>
<div class="price">
<p>¥{{item.p_price}}</p>
</div>
<div class="count">
<div class="num_box">
<button>-</button>
<input type="text" v-model="item.p_number">
<button>+</button>
</div>
</div>
<div class="total">
<p v-if="item.total === 0">未选择数量</p>
<p v-else>¥{{item.total}}</p>
</div>
</div>
<div class="check_box">
<h2>总计:</h2>
<h2>0</h2>
</div>
</div>
</template>
<script>
import Head from "@/components/Head"
export default {
name: 'Home',
components: {
Head
},
data(){
return{
head_name:"shopCar",
products:[
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eb69512d9d6430d865d457ec52eebb51.png?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"小米11 Ultra",
p_detail:"1.12''GN2|128°超广角|120X超长焦|2K四微曲屏|骁龙888|IP68级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器",
p_price:6499,
p_number:0,
total:0
}
]
}
}
}
</script>
<style scoped>
.car{
width: 1200px;
height: 228px;
border: 2px solid #000;
display: flex;
justify-content: space-around;
align-items: center;
margin: 0 auto;
margin-top: 6px;
overflow: hidden;
}
.pimg{
height: 200px;
}
.car>div{
width: 220px;
height: 250px;
position: relative;
}
.car>div>h2{
margin-top: 12px;
}
.car_head{
width: 1200px;
height: 70px;
border: 2px solid #000;
margin: 0 auto;
display: flex;
justify-content: space-around;
align-items: center;
}
.check_box{
width: 1200px;
height: 70px;
border: 2px solid #000;
margin: 0 auto;
margin-top: 12px;
position: relative;
}
.check_box>h2{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.check_box>h2:first-child{
right: 200px;
}
.check_box>h2:last-child{
left: 1002px;
}
.pdetail>p{
font-size: 12px;
color: #909399;
}
.pdetail>p,.price>p,.total>p,.num_box{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.price>p,.total>p,.num_box{
font-size: 22px;
left: 50%;
transform: translateX(-50%);
}
.num_box{
width: 200px;
height: 36px;
display: flex;
justify-content: space-around;
}
.num_box>input{
width: 86px;
font-size: 22px;
padding-left: 6px;
text-align: center;
}
.num_box>button{
width: 36px;
}
</style>
2.第二步需要在methods里添加函数downPrice(index)和addPrice(index)对购买数量的两个按钮分别绑定实现加法和减法的功能,这里之所以要传递形参index是因为需要根据数组的下标来更改该下标所对应的商品的总价。
代码如下:
methods:{
addPrice(data){
this.products[data].p_number += 1;
this.products[data].total = this.products[data].p_number * this.products[data].p_price;
},
downPrice(data){
if(this.products[data].p_number > 0){
this.products[data].p_number -= 1;
this.products[data].total = this.products[data].p_number * this.products[data].p_price;
}
}
}
这样我们就实现了对单个商品的总价的修改功能,(由于computed计算属性里的函数不能传参,不能获取该项商品在数组内所对应的下标,因此目前只想到了用这种方法来解决单个商品相加的需求)注意:这里的input是与数组每一项的p_number双向绑定的,而每一项的总价又在两个加减函数中说明了等于该项的单价乘以购买数量。
此时箭头处的的单品总价已经可以随着购买数量的变化而改变了,但是所有商品的总价还不能变的,这里我们就用计算属性来计算总价。
3.先添加几组假数据让购物车看起来更加真实。
数据在此(自取):
products:[
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eb69512d9d6430d865d457ec52eebb51.png?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"小米11 Ultra",
p_detail:"1.12''GN2|128°超广角|120X超长焦|2K四微曲屏|骁龙888|IP68级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器",
p_price:6499,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/34caee2c867bfd8c5e0dc2d8c663e121.jpg?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"小米11 Pro",
p_detail:"1.12''GN2|骁龙888|2K四微曲屏|IP68级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器",
p_price:4999,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/cb554f30eaa0316b0a736c3d59f21584.png?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"小米11 青春版",
p_detail:"轻薄、多彩 / 骁龙780G / 专业电影相机,前置超级夜景 / AMOLED 柔性直屏 / 超线性立体声双扬声器",
p_price:2299,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/d47f7ecaa04d92bf2790d4a5d53d9099.png?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"黑鲨4 Pro",
p_detail:"骁龙888 | 增强版UFS3.1+SSD磁盘阵列系统 | 高品质双扬声器,DXOMARK音频总分第一名 | 120W极速闪充+4500mAh双电竞电池 | 磁动力升降肩键 | 144Hz 三星E4屏幕",
p_price:4499,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/b3553083a4975325eab6470d94465548.jpg?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"小米10S",
p_detail:"骁龙870 | 对称式双扬立体声 | 1亿像素 8K电影相机 | 33W有线快充 | 30W无线快充 | 10W反向充电 | 4780mAh超大电池 | LPDDR5+UFS3.0+Wi-Fi 6 | VC液冷散热 | 双模5G",
p_price:3299,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/68217751d12b1bfd2f9766e458b5e2dd.jpg?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"Redmi K40 Pro",
p_detail:"骁龙888 / E4 旗舰直屏 / 120Hz高刷 / 杜比全景声 / 4520mAh大电量 / WiFi 6 增强版 / 7.8mm轻薄机身 / 多功能NFC / 红外遥控",
p_price:3699,
p_number:0,
total:0
},
{
img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/73617424da6ff6b64f9c630387bca874.jpg?thumb=1&w=200&h=200&f=webp&q=90",
p_name:"Redmi K40",
p_detail:"骁龙870 / 新一代 E4 AMOLED旗舰直屏 / 杜比全景声 / 7.8mm轻薄机身设计 / 4520mAh大电量/ 360Hz 三指触控 / 120Hz 高刷新 / X轴线性马达 / NFC / 红外遥控",
p_price:2199,
p_number:0,
total:0
}
]
此时的渲染效果是这样的:
看起来还是像那么回事的。
4.接下来就要用到计算属性了,我们在computed里申明一个方法,类似于watch里的属性会随时被监听一样,子不过computed里的逻辑与watch相反,其值是也随着与其相关的值的变化而被动变化,此例中总价应该是每一个单品的总价和,因此我们可以遍历products数组,然后将每一项的总价相加以得到总价。
代码如下:
all:function(){
let all = 0;
for(var i = 0;i < this.products.length;i ++){
all += this.products[i].total;
}
return all;
}
这里的all会就是该函数中返回的products数组中每一项的total的和,all可以直接通过双花括号渲染到视图层里。
因此我们还需要将html代码中的总计部分修改成这样:
<div class="check_box">
<h2>总计:</h2>
<h2>¥{{all}}</h2>
</div>
这样一来all就会经过处理(本例中是求每一项total的和,其他操作也可以)后,直接渲染到页面上了。
再来试一试:
此时我们购买最后三种商品试一试,3299+14796+4398=22493,结果正确。
总之,vue的computed就是将某个参数在computed中经过处理后再直接返回,而页面上也可以直接通过双花括号来渲染,极大的提高了开发效率,降低了开发难度。