<div id="example">
{{ message.split('').reverse().join('') }}
</div>
上面的代码是在模板里实现字符串翻转的逻辑,这样直接写在模板里不仅会是模板过重且难以维护。所以应当使用计算属性。
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
<script>
export default {
data() {
return {
message: 'Hello'
}
},
computed: {
reversedMessage: function() {
return this.message.split('').reverse().join('')
}
}
}
</script>
1. 计算属性缓存(computed) vs 方法(methods)
其实我们可以通过在表达式中调用方法来达到同样的效果:
<p>Reversed Message: "{{ reversedMessage() }}"</p>
/*在组件中*/
<script>
export default {
methods: {
reversedMessage: function(){
return this.message.split('').reverse().join('')
}
}
}
</script>
这两种方法都可以达到我们的目的,为什么我们建议用计算属性呢?
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时才会重新求值。即只要message没有发生改变,多次访问reverseMessage,计算属性会立即返回之前的计算结果,而不必再次执行函数。相比之下,每当触发重新渲染时,调用方法总会再次执行函数。
总之,数据量大,需要缓存的时候用computed;每次确实需要重新加载,不需要缓存时使用methods.
2. computed vs watch
vue提供了一种更加通用的方式来观察和响应vue实例上的数据变动:watch属性
<div id="demo">{{fullName}}</div>
export default {
data() {
return {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
},
watch: {
firstName: function(val) {
this.fullName = val + '' + this.lastName
},
lastName: function(val) {
this.fullName = this.firstName + '' + val
}
}
}
上面的代码是命令式的和重复的,如果采用computed属性,可以写成如下形式:
export default {
data() {
return {
firstName: 'Foo',
lastName: 'Bar'
}
},
computed: {
fullName: function() {
return this.firstName + this.lastName
}
}
}
很明显computed更加智能简洁一些,但是当需要在数据变化时执行异步或者开销比较大的情况下,用watch比较合适。
3. computed的get和set方法
计算属性默认只有getter,不过在需要时也可以定义一个setter
<script>
export default {
computed: {
fullName: {
get: function() {
return this.firstName + '' + this.lastName
},
set: function() {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[name.length-1]
}
}
}
}
</script>
现在再运行vm.fullName = 'John Doe’时,setter会被调用,vm.firstName和vm.lastName也相应地会被更新。