4.计算属性
本节要实现的功能超级简单,字符串反转:
js 实现
js 实现字符串反转还是蛮简单的:
"你好,Vue".split('').reverse().join(''); // 先分割成数组,再反转数组,然后再拼接成字符串
完整版如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.bootcss.com/vue/2.2.6/vue.js"></script>
</head>
<body>
<div id="root">
<h1>{{message}}</h1>
</div>
<script>
let data = {
_message: "你好,Vue"
};
Object.defineProperty(data, 'message', {
enumerable:true,
get: function() {
return this._message.split('').reverse().join('');
}
});
var vm = new Vue({
el: '#root',
data:data
})
</script>
</body>
</html>
我们采用动态添加属性的方式来动态添加 message
变量。但是,Vue 是不能识别动态添加的属性的,因此,我们要设置该属性的可枚举属性 enumerable
为 true
;
vue 实现
现在,来看看 vue 如何实现该功能:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.bootcss.com/vue/2.2.6/vue.js"></script>
</head>
<body>
<div id="root">
<h1>{{reversedMessage}}</h1>
</div>
<script>
let data = {
message: "你好,Vue"
};
var vm = new Vue({
el: '#root',
data:data,
computed:{
reversedMessage: function() {
return this.message.split('').reverse().join('');
}
}
})
</script>
</body>
</html>
我们使用了计算属性来实现。在 computed
中声明了一个计算属性 reversedMessage
,在里面定义了反转字符串的方法,这将作用于 vm.reversedMessage
的 getter
。该过程和我们刚才用 defineProperty
来定义属性的 getter
还有点相似呢。
细心的人会发现,使用方法也是可以实现的:
<div id="root">
<h1>{{reversedMessage()}}</h1>
</div>
<script>
let data = {
message: "你好,Vue"
};
var vm = new Vue({
el: '#root',
data:data,
methods:{
reversedMessage: function() {
return this.message.split('').reverse().join('');
}
}
})
</script>
那么,计算属性和方法有什么区别呢?在这个例子,是看不出区别的。
属性 VS 方法
我们来看下面的例子:
<div id="root"></div>
<script>
let data = {
message: "你好,Vue"
};
var vm = new Vue({
el: '#root',
data:data,
methods:{
method_now(){
return Date.now();
}
},
computed:{
computed_now: function () {
return Date.now();
}
}
})
</script>
在控制台中进行比较:
可以看出,methods
每次都会重新计算,而 computed
则会依赖于缓存,除非 computed` 依赖的值发生变化,否则直接调用缓存。
任务表显示
另外,使用计算属性可以让我们的代码可读性更高一些,例如,我们显示未完成的任务列表,通常会想到这样做:
<div id="root">
<h1>全部任务</h1>
<ul>
<li v-for="task in tasks">{{task.description}}</li>
</ul>
<h1>未完成的任务</h1>
<ul>
<li v-for="task in tasks" v-if="task.uncompleted">{{task.description}}</li>
</ul>
</div>
<script>
let data = {
tasks:[
{description:"编程",uncompleted:true},
{description:"锻炼",uncompleted:false},
{description:"阅读",uncompleted:true},
{description:"睡觉",uncompleted:false}
]
};
var vm = new Vue({
el: '#root',
data:data,
})
</script>
如果使用计算属性,可以使可读性更强,同时还可以再多个地方复用:
<div id="root">
<h1>全部任务</h1>
<ul>
<li v-for="task in tasks">{{task.description}}</li>
</ul>
<h1>未完成的任务</h1>
<ul>
<li v-for="task in umcompletedtasks">{{task.description}}</li>
</ul>
</div>
<script>
let data = {
tasks:[
{description:"编程",uncompleted:true},
{description:"锻炼",uncompleted:false},
{description:"阅读",uncompleted:true},
{description:"睡觉",uncompleted:false}
]
};
var vm = new Vue({
el: '#root',
data:data,
computed:{
umcompletedtasks: function(){
return this.tasks.filter(function(){
return task.uncompleted;
});
}
}
})
</script>
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。