计算属性
模板内的表达式非常便利,但是设计他们的初衷是用于简单运算的。在模板中加入太多的逻辑会让模板过重且难以维护,
<div id=“example”>
{{message.split('').reverse().join('')}}
</div>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。
#基础例子
<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('') } } })这里我们声明了一个计算属性
reversedMessage
#计算属性缓存vs方法
你可能已经注意到我们可以通过表达式中调用方法来达到同样的效果
<p>Reversed message: "{{ reversedMessage() }}"</p>
methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的
依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversed
Message
计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:
computed: { now: function () { return Date.now() } } |
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?
假设我们有一个性能开销比较大的计算属性A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。
如果没有缓存,我们将不可避免的多次执行 A 的 getter!
#计算属性vs侦听属性
vue提供了一种更实例的方式,来观察和响应Vue实例上的数据变动:侦听属性,当你有一些数据需要随着其他的数据的变动而变动的时候
,很容易滥用watch通常更好的做法是使用计算属性而不是命令式的 watch
回调
侦听器:
这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,
这个方式是最有用的。