什么是计算属性?
我们暂且先不说什么是计算属性,现在有一个店铺:起送金额¥20,一个客户买了红烧牛肉面,信息如下:
{id:1,price:10,name:'红烧牛肉面',count:1}//分别对应 商品ID 价格 名字 购买数量
假设我们有这样的结构
var vm = new Vue({ el: '#app', data:{ good:{id:1,price:10,name:'红烧牛肉面',count:1}, } })
<div id="app"> <h2>本店起送金额¥20</h2> <div> 您购买了{{good.name}}共{{good.count}}份===¥{{good.price}}/份 </div> <div>总价:【这里我想显示总价】</div></div>
那么,我想在显示总价的地方计算出总价,我们会怎么写?
<div>总价:{{good.price*good.count}}</div>
老板说,我想打个8折,我们又改成
var vm = new Vue({ el: '#app', data:{ good:{id:1,price:10,name:'红烧牛肉面',count:1}, discount:0.8 } }) <div>总价:{{(good.price*good.count)*discount}}</div>
老板说20起送啊,买东西太少,没有配送费不划算啊,配送费5块!
var vm = new Vue({ el: '#app', data:{ good:{id:1,price:10,name:'红烧牛肉面',count:1}, discount:0.8, deliver:5 } }) <div>总价:{{(good.price*good.count)*discount+deliver}}</div>
随着要求的增加,计算总价的表达式会越来越长,这时候视图层(view)的逻辑越来越复杂,代码会越来越臃肿,变得难以维护。怎么给视图减负?这就用到我们今天要说的 计算属性
我对计算属性的理解是:计算属性是需要复杂的逻辑和很多组件基础状态最后才能得到其正确值的属性
计算属性怎么用?
1 定义:Vue里面,就像所有的方法都在methods中一样,所有的计算属性都写在 vue 实例的 computed 属性中,这个计算属性就是一个函数,返回值为最后属性的值(下面totalPrice 就是一个计算属性)
computed:{ totalPrice(){ return (this.good.price*this.good.count)*this.discount+this.deliver; } }
2 使用:定义完成之后,我们就可以像用普通属性一样去用计算属性,有没有很简单?
来来来我们看怎么用计算属性实现这个功能
<div id="app"> <h2>本店起送金额¥20</h2> <h3>配送费¥5</h3> <div> 您购买了{{good.name}}共{{good.count}}份===¥{{good.price}}/份 </div> <div>总价:{{totalPrice}}</div></div>
var vm = new Vue({ el: '#app', data:{ good:{id:1,price:10,name:'红烧牛肉盖饭',count:1}, discount:0.8, deliver:5 }, computed:{ totalPrice(){ return (this.good.price*this.good.count)*this.discount+this.deliver; } } })
计算属性的方法可以包含很多繁重的逻辑,最终返回我们需要的值
通过计算属性的使用,View层的代码会变的非常精简,且容易维护
不适用计算属性时,我们也可以使用method代替
var vm = new Vue({ el: '#app', data:{ peoples:[ //是否发送过简历 是否同意面试 是否面试过 面试人员名字 {sended:false,agree:false,faced:false,name:"唐森"}, {sended:true,agree:false,faced:false,name:"沙僧"}, {sended:true,agree:true,faced:false,name:"天蓬"}, {sended:true,agree:true,faced:true,name:"悟空"}, ] }, methods: { facedStatus(item) { var status_label='面试状态未知'; if(!item.sended){ status_label='未发送简历'; } if(item.sended&&!item.agree){ status_label='已发送简历,未同意面试'; } if(item.sended&&item.agree&&!item.faced){ status_label='已发送简历,已同意面试,但未面试'; } if(item.sended&&item.agree&&item.faced){ status_label='已发送简历,并同意面试,已经面试过'; } return status_label; } } })
<div id="app"> <div v-for="(item,index) in peoples"> {{index}}----{{item.name}} <!-- 逻辑比较复杂,可以尝试使用methods --> <span>{{facedStatus(item)}}</span> </div></div>
运行效果
作者:小枫学幽默
链接:https://www.jianshu.com/p/3681efcda8b0