计算属性computed和监听器watch的区别
引用官方文档例子:
computed:
模板的设计初衷就是用于简单运算的,如果在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
此时模板中的表达式不再是简单的声明式逻辑,同时如果想在模板中多次复用,就会显得更加难以维护。所以,对于任何复杂逻辑,使用计算属性computed更为合适。
例子:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
输出结果:
Original message: “Hello”
Computed reversed message: “olleH”
这里我们声明了一个计算属性:reversedMessage。我们提供的函数将用作 property vm.reversedMessage 的 getter 函数:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
由于 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。
计算属性缓存 vs 方法
你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
用调用方法得到最终的结果是相同的,但是最大的区别就在于:
- 计算属性是基于它们的响应式依赖进行缓存的,只有相关响应式依赖发生改变时它们才会进行重新计算。
- 这就意味着,message未发生改变,reversedMessage 返回的值永远都是之前的计算结果
- 如果有一个性能消耗较大的计算属性,并且需要大量复用,多次调用方法将会造成性能浪费。
计算属性的 setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
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[names.length - 1]
}
}
}
现在再运行 vm.fullName = ‘John Doe’ 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。