参考:《Vue.js实战》梁灏
1 什么是计算属性
在模板中,如果表达式过长,或逻辑更为复杂时,就会变得臃肿甚至难以阅读和维护:
<div>
{{ text.split(",").reverse().join(",") }}
</div>
可以改用如下的计算属性进行改写:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>什么是计算属性</title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
{{ text.split(",").reverse().join(",") }}
<br>
{{ reverseText }}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
text:'123,456',
},
computed:{
reverseText:function(){
//这里的this指向的是当前的Vue实例
return this.text.split(",").reverse().join(",");
}
}
});
</script>
</body>
</html>
2 计算属性的用法
计算属性还可以依赖多个Vue实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>计算属性用于多个Vue实例</title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
总价:{{ prices }}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
p1:[
{
name:"Iphone 7 ",
price:7199.2,
count:2
},
{
name:"Ipad",
price:2888,
count:1
}
],
p2:[
{
name:"apple",
price:3,
count:5
},
{
name:"banana",
price:2,
count:10
}
]
},
computed:{
prices:function(){
var prices = 0;
for(var i = 0;i < this.p1.length;i++){
prices += this.p1[i].price * this.p1[i].count;
}
for(var i = 0;i < this.p2.length;i++){
prices += this.p2[i].price * this.p2[i].count;
}
return prices;
}
}
});
</script>
</body>
</html>
每一个计算属性都包含一个getter和setter:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>getter & setter</title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
姓名:{{ fullName }}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
firstName:"Jack",
lastName:"Green"
},
computed:{
fullName:{
//getter,用于获取
get:function(){
return this.firstName + ' ' + this.lastName;
},
//setter,写入时触发
set:function(newValue){
var names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
}
}
});
app.fullName = "Mick viki";
</script>
</body>
</html>
通常我们只会用默认的getter方法来读取一个计算属性,很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter和setter都声明。
计算属性还有两个很实用的小技巧:一是计算属性可以依赖其他计算属性;二是计算属性不仅可以依赖当前Vue实例的数据,还可以依赖其他实例的数据:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>计算属性多实例依赖</title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app1"></div>
<div id="app2">
{{ reverseText }}
</div>
<script type="text/javascript">
var app1 = new Vue({
el:"#app1",
data:{
text:'123,456'
}
});
var app2 = new Vue({
el:"#app2",
computed:{
reverseText:function(){
//这里依赖的是实例app1的数据text
return app1.text.split(",").reverse().join(",");
}
}
});
</script>
</body>
</html>
3 计算属性缓存
你可能发现,调用methods里的方法也可以与计算属性起到同样的作用,改写本文的第一个实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>计算属性缓存</title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 注意,这里是方法,所以要带 () -->
{{ reverseText() }}
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
text:'123,456'
},
methods:{
reverseText:function(){
//这里的this指向的是当前Vue实例
return this.text.split(',').reverse().join(",");
}
}
});
</script>
</body>
</html>
相比之下,methods方式同样可以实现效果,甚至还可以接受参数,使用起来更灵活,那么,计算属性的优势在哪?原因是计算属性是基于它的依赖缓存的
。一个计算属性所依赖的数据发生变化时,它才会重新取值,所以只要text不改变,计算属性也就不更新