14.1computed计算属性
- 表达式如果过长,或逻辑更为复杂时,就会变得臃肿甚至难以阅读和维护,在遇到复杂的逻辑时应该使用计算属性。
- 计算属性还可以依赖多个Vue实例的数据,只要其中任一数据发生变化,计算属性就会重新执行,视图也会更新。例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vue.jscomputed起步练习-计算购物车总价</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- 通过CDN引入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#app{
height: 100%;
}
.container {
display: flex;
width: 85%;
margin: 0 auto;
flex-direction: column;
}
.item {
display: flex;
border: 1px solid #6495ED;
width: 90%;
height: 100px;
border-radius: 10px;
margin-bottom: 10px;
/* 垂直方向居中 */
align-items: center;
padding-left: 10px;
padding-right: 10px;
margin-bottom: 55px;
}
.item-id {
flex: 1 1 5%;
}
.item-pic {
flex: 1 1 15%;
}
.item-name {
flex: 1 1 30%;
}
.item-price {
flex: 1 1 20%;
}
.item-count {
flex: 1 1 30%;
}
.goods-count {
width: 20px;
}
.total-price {
width: 100%;
height: 50px;
bottom: 0;
position: fixed;
border: 1px solid darkgrey;
display: flex;
justify-content: space-between;
align-items: center;
border-right: none;
border-left: none;
background-color: white;
}
.total {
display: flex;
flex: 1 1 40%;
}
.total-price1 {
font-size: 30px;
left: 0;
color: yellow;
flex: 1 1 20%;
}
.account {
outline: none;
border-radius: 10px;
font-size: 25px;
color: white;
background-color: orangered;
border-style: none;
width: 100px;
}
.total-left{
display: flex;
flex: 1 1 30%;
padding-left: 25px;
}
.total-right{
display: flex;
height: 100%;
padding-right: 25px;
}
.link2{
text-decoration: none;
color: black;
}
</style>
</head>
<body>
<!-- vueapp的根容器 -->
<div id="app">
<div class="container">
<div class="item" v-for="goods in goodlist" @click="goweb()">
<div class="item-id">
{{goods.id}}
</div>
<div class="item-pic">
<img :src="goods.pic" style="width:70px;height: 65px;">
</div>
<div class="item-name">
<a :href="goods.url" class="link2">{{goods.name}}</a>
</div>
<div class="item-price">
{{goods.price}}
</div>
<div class="item-count">
<button type="button" @click="goods.count-=1" :disabled="goods.count===0">-</button>
<input type="text" v-model="goods.count" class="goods-count" />
<button type="button" @click="goods.count+=1">+</button>
</div>
</div>
</div>
<div class="total-price">
<div class="total-left">
<h3 class="total">Total price:<p class="total-price1">¥{{totalPrice}}</p></h3>
</div>
<div class="total-right">
<button type="button" class="account" @click="windows()">结算</button>
</div>
</div>
</div>
<script type="text/javascript">
// 实例化一个vue对象
var app = new Vue({
el: '#app',
data: {
goodlist: [{
id: 1,
name: 'iphone8',
price: 6000,
count: 0,
pic: 'img/iphone8.jpg',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.56.27641200sTip3z&id=585322790611&skuId=3996743665792&user_id=1776456424&cat_id=2&is_b=1&rn=e6212487ef4624bae57c2788fb78f5ad'
},
{
id: 2,
name: 'iphoneX',
price: 7000,
count: 0,
pic: 'img/iphoneX.jpg',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.6.6a247a79uE2oSn&id=583972739234&skuId=4100773710875&user_id=197232874&cat_id=2&is_b=1&rn=117b243673c231b787268345203cf2af'
},
{
id: 3,
name: 'iphone xs max',
price: 8000,
count: 0,
pic: 'img/iphone xs max.png',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.14.7106109cmbLRp4&id=581152918962&skuId=3880557185834&user_id=197232874&cat_id=2&is_b=1&rn=6cc9df1873d25c70b5c8d4816c5d243b'
},
{
id: 4,
name: '小米9',
price: 2999,
count: 0,
pic: 'img/xiaomi9.jpg',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.1.5cfb99f72u7XJG&id=587578411300&skuId=4164787995400&standard=1&user_id=2024314280&cat_id=2&is_b=1&rn=b3aba07d7277d1ba9d803409bc63e63d'
},
{
id: 5,
name: '红米note7',
price: 999,
count: 0,
pic: 'img/RedmiNote7.jpg',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.13.9f964d25RnU6WY&id=585890686011&skuId=3973009493052&standard=1&user_id=2024314280&cat_id=2&is_b=1&rn=f0411949ffed3657397b61c91b4e5a1f'
},
{
id: 6,
name: 'Redmi6a',
price: 569,
count: 0,
pic: 'img/Redmi6a.jpg',
url:'https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.13.9f964d25RnU6WY&id=585890686011&skuId=3973009493052&standard=1&user_id=2024314280&cat_id=2&is_b=1&rn=f0411949ffed3657397b61c91b4e5a1f'
}
]
},
methods: {
},
computed: {
totalPrice: function() {
var totalPrice = 0;
var len = this.goodlist.length;
for (var i = 0; i < len; i++) {
totalPrice += this.goodlist[i].price * this.goodlist[i].count;
}
return totalPrice;
},
windows: function() {
var totalPrice = 0;
var total = 0
var len = this.goodlist.length;
for (var i = 0; i < len; i++) {
totalPrice += this.goodlist[i].price * this.goodlist[i].count;
total += this.goodlist[i].count;
}
alert("你购买了" + total + "件商品," + "需支付总价为:" + totalPrice + "元")
}
}
})
</script>
</body>
</html>
运行结果:
image.png
改变购买的数量,结果为:
image.png
总价会实时更新。
14.2过滤器
- 注意:过滤器应当用于处理简单的文本转换,如果要实现更为复杂的数据变换,因该使用计算属性。
- Vue.js支持在{{}}插值的尾部添加一个管道符“|”对数据进行过滤,经常用于格式化文本。过滤的规则是自定义的,通过给Vue实例添加选项filter来设置。
<div id="app">
{{date|formatDate}}
</div>
<script type="text/javascript">
//在月份、日期和小时等小于10前面补0
var paddate=function(value){
return value<10?'0'+value:value;
};
// 实例化一个vue对象
var app = new Vue({
el: '#app',
data: {
date:new Date()
},
filters:{
formatDate:function(value){//这里的value就是需要过滤的数据
var date=new Date(value);
var year=date.getFullYear();
var month=paddate(date.getMonth(+1));
var day=paddate(date.getDate());
var hours=paddate(date.getHours());
var minutes=paddate(date.getMinutes());
var seconds=paddate(date.getSeconds());
//将整理好的数据返回出去
return year+'-'+month+'-'+day+' '+hours+':'+minutes+':'+seconds;
}
},
mounted:function(){
var _this=this;
this.timer=setInterval(function(){
_this.date=new Date();//修改数据date
},1000);
},
beforeDestroy:function(){
if(this.timer){
clearInterval(this.timer);
}
}
})
</script>
运行结果:
image.png
- 过滤器也可以串联,而且可以接收参数
串联:{{message|filterA|filterB}}
接收参数:{{message|filterA('arg1','arg2')}}
网友评论