computed意为计算属性,官方称任何复杂逻辑,你都可以使用计算属性。
下面就购物车的小例子对computed进行讲解。
下面看2张运行截图:
20171009152723371.png
20171009152754526.png
首先我们看js代码:
var vm = new Vue({ el:"#materialTest", data:{ //allMaterialList定义了所有的货物列表,属性有id,名称,数量,单价和是否再购物车中5个属性 allMaterialList:[ {id:0,name:"香蕉",num:1,unitPirce:5,isSelect:false}, {id:1,name:"苹果",num:1,unitPirce:1,isSelect:false}, {id:2,name:"菠萝",num:1,unitPirce:2,isSelect:false}, {id:3,name:"桃子",num:1,unitPirce:6,isSelect:false}, {id:4,name:"番茄",num:1,unitPirce:4,isSelect:false} ] }, methods:{ //购物车增加删除的方法 changeMaterial:function(item,type){ if(!item){ item = this.allMaterialList[0]; } var temp = this.allMaterialList[item.id]; temp.isSelect = type; //注意,这里改变数组,或对象,要用下面的方式,简单的push是不能触发双向绑定的。 Vue.set(this.allMaterialList, item.id, temp); } }, computed:{ //computed计算选中的的物品 notSelectMaterialList:function(){ return this.allMaterialList.filter(function (item) { return item.isSelect === false }) }, //computed计算未选中的的物品 isSelectMaterialList:function(){ return this.allMaterialList.filter(function (item) { return item.isSelect === true }) }, //computed计算商品总价格 allCount:function(){ var count = 0; for(var i = 0 ; i < this.isSelectMaterialList.length ; i++){ count += this.isSelectMaterialList[i].num * this.isSelectMaterialList[i].unitPirce; } return count; } }, created:function(){ this.changeMaterial('',true); } })
上面的js代码基本上显示了整个逻辑,购物车里面的货物可以增减,最终allCount来显示总价格。再看html代码:
<div id="materialTest"> <div class="material-list"> <p v-show="isSelectMaterialList.length > 0">已经选择的水果</p> <div class="item-list" v-for="item in isSelectMaterialList"> <span v-text="'品名:'+item.name"></span> <span v-text="'单价:'+item.unitPirce"></span> <span>数量:<input type="number" v-model="item.num" min="0"></span> <span @click="changeMaterial(item,false)">-</span> </div> </div> <div class="all-material-list"> <p v-show="notSelectMaterialList.length > 0">所有水果</p> <div class="item-list" v-for="item in notSelectMaterialList"> <span v-text="'品名:'+item.name"></span> <span v-text="'单价:'+item.unitPirce"></span> <span @click="changeMaterial(item,true)">+</span> </div> </div> <p>总价格:${{allCount}}</p> </div>
这里贴上完整的代码供大家参考:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>computed</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.4.4/dist/vue.min.js"></script> <style> .item-list span:last-child{ border:1px solid; padding:0px 5px; cursor: pointer; } .item-list{ margin-bottom: 10px; } </style></head><body> <div id="materialTest"> <div class="material-list"> <p v-show="isSelectMaterialList.length > 0">已经选择的水果</p> <div class="item-list" v-for="item in isSelectMaterialList"> <span v-text="'品名:'+item.name"></span> <span v-text="'单价:'+item.unitPirce"></span> <span>数量:<input type="number" v-model="item.num" min="0"></span> <span @click="changeMaterial(item,false)">-</span> </div> </div> <div class="all-material-list"> <p v-show="notSelectMaterialList.length > 0">所有水果</p> <div class="item-list" v-for="item in notSelectMaterialList"> <span v-text="'品名:'+item.name"></span> <span v-text="'单价:'+item.unitPirce"></span> <span @click="changeMaterial(item,true)">+</span> </div> </div> <p>总价格:${{allCount}}</p> </div> <p>Tips:总结,使用computed计算出了3个变量,notSelectMaterialList、isSelectMaterialList、allCount。大大简化了程序,computed还会缓存计算结果,比watch强。再者,当结果没发生变化时,并不会触发函数,但不意味computed没有观察到变化。</p></body><script> var vm = new Vue({ el:"#materialTest", data:{ allMaterialList:[ {id:0,name:"香蕉",num:1,unitPirce:5,isSelect:false}, {id:1,name:"苹果",num:1,unitPirce:1,isSelect:false}, {id:2,name:"菠萝",num:1,unitPirce:2,isSelect:false}, {id:3,name:"桃子",num:1,unitPirce:6,isSelect:false}, {id:4,name:"番茄",num:1,unitPirce:4,isSelect:false} ] }, methods:{ changeMaterial:function(item,type){ if(!item){ item = this.allMaterialList[0]; } var temp = this.allMaterialList[item.id]; temp.isSelect = type; //注意,这里改变数组,或对象,要用下面的方式,简单的push是不能触发双向绑定的。 Vue.set(this.allMaterialList, item.id, temp); } }, computed:{ notSelectMaterialList:function(){ //使用计算属性过滤要显示的物品 return this.allMaterialList.filter(function (item) { return item.isSelect === false }) }, isSelectMaterialList:function(){ return this.allMaterialList.filter(function (item) { return item.isSelect === true }) }, allCount:function(){ var count = 0; for(var i = 0 ; i < this.isSelectMaterialList.length ; i++){ count += this.isSelectMaterialList[i].num * this.isSelectMaterialList[i].unitPirce; } return count; } }, created:function(){ th- s.- hangeMaterial('',true); } })</script></html>
后记:适当运用computed能大大简化我们的代码,计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter,不过运用的少。最后欢迎评论,一起探讨,共同进步.
作者:伊泽瑞尔灬
链接:https://www.jianshu.com/p/5388a0b41613