Computed 与 Mustache 的纠葛
初学Vue,大部分人知道 {{ }} 这个双大括号是用来绑定 data 里的属性的,这被称为 Mustache 语法,即文本插值。Vue 里也提到,我们可以在 {{ }} 里进行一些简单的运算,例如字符串拼接。但如果我们想要在里面进行更为复杂的运算,尽管是可以实现的,但 Vue 官方并不推荐这么做。
Vue 官方推荐对于模板(即双大括号)里的复杂计算,任何时候都应当使用 computed 计算属性,computed 与 methods 的区别是 Vue 里经典的问题,computed 必须 return 一个对象,这使得 computed 里面的数据可以被缓存起来(闭包原理)。接下来,我们引用一下 Vue 官方的案例来看看这个案例:
<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 函数居然像 data 里的 message 一样可以在 {{ }} 里被使用!
这是因为在计算属性里的函数 reversedMessage 与 data 里 message 建立了依赖关系,这当然得益于 Vue 在底层的一些实现。所以,如果你以后在阅读别人的源码时看到了这种做法,可不要再一头雾水。
那,这里面到底是什么原理呢?
可以看到,computed 是一个对象,在对象中,有访问器属性,即最重要的 getter 与 setter 两个方法,getter 方法将在对象属性被访问时调用,setter 方法在对象属性被更改时调用。在计算属性 computed 里 Vue 隐式地将我们创建地函数放置在 getter 中,当我们使用 data 里的数据时,getter 会告诉 Vue,reversedMessage 函数调用了 data 对象的属性。reversedMessage 函数还 return 出来这个 message,其被保存了起来,以实现可读取。Vue 将这个更改过的 message 代替原来的 message,并将其渲染到 {{ }} 中。
补充阅读:访问器属性与 Vue 响应式原理
https://www.jianshu.com/writer#/notebooks/41336708/notes/88489001