概念:
计算属性,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。
注意,计算属性也是Vue中的一种属性
举一个简单例子,例如存在一个商品,其基本属性有单价、数量,在购买的时候往往都是多个一起购买,这种时侯的总价就可以看做成一个计算属性。
上代码
示例
<body>
<div id="app">
<h2>苹果</h2>
<div>单价:<input v-model="num"></div>
<div>价格:<input v-model="price.toFixed(2)"></div>
<div>总价:{{num*price}}</div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
var vm=new Vue({
el:'#app',
data:{
num:0,
price:2.00
},
methods:{
}
});
</script>
从Vue的语法就可以知道了,{{}}这个里面的东西,可以是函数表达式,也可以是Vue的属性值,而这里的{{num*price}}就属于函数表达式了,因此这种方法可以解决该需求。但是往往应用场景不会这么简单,如果都直接在{{}}中使用表达式的话,不仅仅会显得很low,而且还会使得代码冗余度很高,不便于后期的维护。
于是就想到了那使用函数的方式实现,反正{{}}这个里面都是可以解析函数的,让这个函数有返回值不就行了。
这个想法好,试一试,上代码
<div>总价:{{TotalPrices()}}</div>
Vue中的methods中添加如下代码:
TotalPrices(){
return this.num*this.price
}
这不,也可以的嘛,一开始的那种方式确实便于维护,这不引用了函数的方式,我在函数里面写逻辑,不也可以嘛,还要啥自行车啊!!!
我一开始也是这样想的,但是再看下面例子。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>江河三千里</title>
<script type="text/javascript" src="http://ljy0427.online/js/vue.js"></script>
<style>
div {
margin-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<h2>苹果</h2>
<div>单价:<input v-model="num"></div>
<div>价格:<input v-model="price.toFixed(2)"></div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
var vm = new Vue({
el: '#app',
data: {
num: 2,
price: 2.00
},
methods: {
TotalPrices() {
console.log("计算了");
return this.num * this.price
}
}
});
</script>
</html>
这里的区别就是,我多加了几个div,都放上总价,也就是多个地方都用到了这个总价
从图片中就可以看了,这个函数执行了6次。这里看似没毛病,但考虑一下,在开发中,如果很多地方都用到了这个东西,那岂不是要调用很多次,这样不就同时就浪费了很多的资源嘛,这样看来这种方法虽然也可以,但是还欠缺一点,于是就有了computed这一计算属性。
computed
其实前面都是铺垫,主角来了,之所以会有这么东西,是因为它有一个优秀的机制——缓存机制。
如何使用
computed计算属性,是一个对象的形式存在的,可以直接使用,既然是对象,那么里面可以存在很多子对象
首先将这个总价定义成一子对象的形式:
var vm = new Vue({
el: '#app',
data: {
num: 2,
price: 2.00
},
computed:{
TotalPrices:{
}
},
methods: {
// TotalPrices() {
// console.log("计算了");
// return this.num * this.price
// }
}
});
就会发现这里这样定义之后,提示缺少getter方式,既然提到了getter方法,那么就可以联想到计算属性是通过Object.defineProperty实现的了。
TotalPrices:{
get(){
return this.num * this.price
}
}
为其添加get()就能看到想要的结果了,并且再向上面一样,多用几次这个总价的属性,看看效果
<body>
<div id="app">
<h2>苹果</h2>
<div>单价:<input v-model="num"></div>
<div>价格:<input v-model="price.toFixed(2)"></div>
<div>总价:<input v-model="TotalPrices"></div>
<div>总价:<input v-model="TotalPrices"></div>
<div>总价:<input v-model="TotalPrices"></div>
<div>总价:<input v-model="TotalPrices"></div>
<!-- <div>总价:{{TotalPrices}}</div> -->
<!-- <div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div>
<div>总价:{{TotalPrices()}}</div> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
var vm = new Vue({
el: '#app',
data: {
num: 2,
price: 2.00
},
computed: {
TotalPrices: {
get() {
console.log("计算了");
return this.num * this.price
}
}
}
});
</script>
</html>
这个时候就会发现,不管这个总价属性被引用了多少次,这个方法只执行了一次,之所以这样,就是因为computed计算属性采用了缓存机制,也就是,当后面的代码中有用到相同的属性值之后,都会从缓存中取出来,这样的话,就会大大的提高了效率。
同时当价格或者数量变化的时候,对应的总价也会发生改变,这个就是因为Vue的机制,当其中有值发生改变的时候,就会重写解析一次代码,也就可以理解成重新构建一次Vue实例。
变一下需求,例如,我就只有这么多钱,计算出我能买几个,无非就是添加一个时间,修改这个计算属性,然后根据set()方法修改对应的值,上代码
<body>
<div id="app">
<h2>苹果</h2>
<div>单价:<input v-model="num"></div>
<div>价格:<input v-model="price.toFixed(2)"></div>
<div>总价:{{totalPrices}}</div>
<div>我有:<input v-model="OwnPrice" @keyup.enter="buy"></div>
<div>可以买:{{buyNum}}个</div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
var vm = new Vue({
el: '#app',
data: {
num: 2,
price: 2.00,
OwnPrice:0,
buyNum:0
},
computed: {
totalPrices: {
get() {
console.log("计算了");
return this.num * this.price
},
set(value) {
this.buyNum=value/this.price
}
}
},
methods: {
buy() {
this.totalPrices=this.OwnPrice
console.log("购买");
}
}
});
</script>
这样确实实现了,但是这却又和计算属性的初衷有出入了,这个计算属性最主要的就是这个get,也就是获取值的功能,你要去修改它,就是另外一回事了。
简写
如果只考虑使用了get方法,那么能不能简写,这个肯定有,我这里这种计算属性的定义方式是将其定义成对象的形式,所以每一次都需要写get方式
这种是对象的定义方式,看看简写形式
totalPrices() {
console.log("计算了");
return this.num * this.price
}
将其定义成一个函数的形式,携带返回值就行,看看效果
神奇嘿,一模一样。
总结
计算属性,也是Vue属性中的一种,其可以直接获取,最大的特点的就是支持计算,并且还具有缓存机制。而且通常情况下,计算属性中的属性值,只会使用到起get方法。
1 条评论
不错