学习笔记《Vue 的响应式编程》
在使用 Vue 实现 SPA 系统的时候,响应式编程是一套最核心的理念,整个系统根据数据对象对页面进行反向渲染,让站点避免结构混乱的问题
举个例子
先从官方文档里面摘录一个响应式编程的例子:
模板部分:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
Vue 部分:
window.vm1 = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
在这个例子中,如果在浏览器的调试工具栏里面运行:
vm1.message = 'time'
则模板中的两个内容都会同时变化,也就是说,作为 computed 方法下面的 reversedMessage 属性的值,会实时监控 message 的值,在 message 值发生变化的时候进行跟随的变化,并渲染到页面中
computed 和 methods 的差别
如果把上面的例子进行简单的替换,模板部分的 reversedMessage 换成 reversedMessage() :
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage() }}"</p>
</div>
Vue 部分把 computed 替换成 methods:
window.vm1 = new Vue({
el: '#example',
data: {
message: 'Hello'
},
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
也会有完全类似的效果(在调试栏输入 vm1.message = 'time'
依然可以保持两个数据的响应),唯一的区别是 computed 会借助缓存以获取更好的性能:
the difference is that computed properties are cached based on their dependencies. A computed property will only re-evaluate when some of its dependencies have changed.
In comparison, a method invocation will always run the function whenever a re-render happens.
Why do we need caching? Imagine we have an expensive computed property A, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on A. Without caching, we would be executing A’s getter many more times than necessary! In cases where you do not want caching, use a method instead.
PS:另一个差别是 mapState 这个方法只能在 computed 中使用,methods 中无效
computed 和 watch 的差别
watch 是依照 AngularJS 的习惯进行的数据监测方式,直接监控某个属性的变化情况,并进行相应的值修改,而 computed 并不监控属性,而是监控方法里面的参数值,看一个使用 watch 的例子
模板部分:
<div id="example">
<p>Original message: "@{{ message }}"</p>
<p>Computed reversed message: "@{{ reversedMessage }}"</p>
</div>
Vue 部分:
window.vm1 = new Vue({
el: '#example',
data: {
message: 'Hello',
reversedMessage: 'olleH',
},
watch: {
message: function (val) {
this.reversedMessage = val.split('').reverse().join('')
}
}
})