1 计算属性 1.1 模板内的表达式是非常便利的,但是它们实际上只用于简单的运算。 在模板中放入太多的逻辑会让模板过重且难以维护。
<div id="test1"> {{str.split(‘‘).reverse().join(‘‘)}} </div> <script> let app1 = new Vue({ el: ‘#test1‘, data: { str: ‘hello world‘ } }); </script>
这种写法的弊端: 在这种情况下,模板不再简单和清晰。在意识到这是反向显示 str 之前, 你不得不再次确认第二遍。当你想要在模板中多次反向显示 str 的时候, 问题会变得更糟糕。 这就是对于任何复杂逻辑,你都应当使用计算属性的原因。 1.2 基本计算属性
<div id="test2"> <p>原始的效果:{{str}}</p> <p>反转后的效果:"{{reverse}}"</p> </div> <script> let app2 = new Vue({ el: ‘#test2‘, data: { str: ‘hello world‘ }, computed: { //computed的getter reverse: function () { return this.str.split(‘‘).reverse().join(‘‘); } } }); </script>
这里声明了一个计算属性 reverse。 提供的函数将用作属性 vm.reverse 的 getter 。
可以打开浏览器的控制台,自行修改例子中的 app2 。 app2.reverse 的值始终取决于 app2.str 的值。可以像绑定普通属性一样在模板中绑定计算属性。 Vue 知道 app2.reverse 依赖于 app2.str ,因此当 app2.str 发生改变时,所有依赖于 app2.reverse 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 是没有副作用,这使得它易于测试和推理。
1.3 计算缓存(计算属性) vs Methods 可以通过调用表达式中的 method 来达到同样的效果
<div id="test2"> <p>原始的效果:{{str}}</p> <p>反转后的效果:"{{reverse}}"</p> <p>反转后的效果:"{{reverseMe()}}"</p> </div> <script> let app2 = new Vue({ el: ‘#test2‘, data: { str: ‘hello world‘ }, computed: { reverse: function () { return this.str.split(‘‘).reverse().join(‘‘); } }, methods: { reverseMe: function () { return this.str.split(‘‘).reverse().join(‘‘); } } }); </script>
我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 str 还没有发生改变,多次访问 reverse 计算属性会立即返回之前的计算结果,而不必再次执行函数。 相比而言,只要发生重新渲染,method 调用总会执行该函数。我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A ,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。
1.4 Computed 属性 vs Watched 属性 Vue 确实提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:watch 属性。 当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。 然而,通常更好的想法是使用 computed 属性而不是命令式的 watch 回调。 比较例子:
<div id="test4">{{fullName}}</div> <div id="test5">{{fullName}}</div> <script> let app4 = new Vue({ el: ‘#test4‘, data: { firstName: ‘Jeson‘, lastName: ‘hu‘, fullName: ‘Jesonhu‘ }, watch: { firstName: function (val) { this.fullName = val +‘ ‘+ this.lastName; }, lastName: function (val) { this.fullName = this.firstName +‘ ‘+ val; } } }); let app5 = new Vue({ el: ‘#test5‘, data: { firstName: ‘Jeson‘, lastName: ‘hu‘ }, computed: { fullName: function () { return this.firstName +‘ ‘+ this.lastName; } } }); </script>
1.5 计算 setter 计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
<div id="test6">{{fullName}}</div> <script> let app6 = new Vue({ el: ‘#test6‘, data: { firstName: ‘Jeson‘, lastName: ‘hu‘ }, 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] } } } }); </script>
现在在运行 app6.fullName = ‘John Doe‘ 时, setter 会被调用, app6.firstName 和 app6.lastName 也相应地会被更新。 2 观察 Watchers 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的 watcher 。 这是为什么 Vue 提供一个更通用的方法通过 watch 选项,来响应数据的变化。 当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。
时间: 2024-11-06 12:09:30