有时我们在获取 Vue 实例的数据时需要对数据进行一些处理,如果模板中多次使用了处理后的数据,使用计算属性来实现会更加方便。虽然大多数情况使用计算属性比较合适,但是在数据变化时需要执行一些异步或者开销较大的操作时,使用侦听器更为有效。
# 计算属性
与定义在 data
中的属性不同,计算属性并不存储值,与大多数其他语言中的计算属性一样,其通过 getter
方法与 setter
方法来提供我们所需要的操作。我们可以在 Vue 实例中使用 computed
属性来声明计算属性。
# getter
方法
下面的例子中通过计算属性将我们输入的字符串逆向输出
<html>
<div id="vue-example-1">
<input type="text" v-model="message">
<p>输出结果:{{reversedMsg}}</p>
</div>
<script>
new Vue({
el: '#vue-example-1',
data: {
message: '', // 定义一个属性来存储值
},
computed: {
// 定义一个计算属性返回逆向的 message
reversedMsg: function () {
return this.message.split('').reverse().join('')
}
}
});
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
上面的例子可以看到 Vue 知道计算属性 reversedMsg
与 message
存在关联,当 message
发生改变时所有依赖 reversedMsg
的绑定也会同步变化。
计算属性缓存
计算属性会基于他们的响应式依赖进行缓存,当一个计算属性多次使用时,如果其依赖的属性没有改变则不会重新计算直接使用上次的结果。例如上面的例子中多次使用 reversedMsg
,只要 message
没有发生变化则会立即返回之前的结果不会重新执行方法。
# setter
方法
计算属性默认只有 getter
方法,但也可以在需要时添加 setter
方法。
下面的例子通过 setter
方法变更 message
<html>
<div id="vue-example-2">
<input type="text" v-model="message">
<p>输出结果:{{reversedMsg}}</p>
<input type="button" value="点击测试 setter 方法" @click="reversedMsg = 'hello Vue'">
</div>
<script>
new Vue({
el: '#vue-example-2',
data: {
message: '',
},
computed: {
reversedMsg: {
// getter 方法
get: function () {
return this.message.split('').reverse().join('')
},
// setter 方法
set: function (newValue) {
this.message = newValue
}
}
}
});
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 侦听器
Vue 通过 watch
来定义侦听器,将一个变量与方法绑定,当这个变量发生变化时就执行这个方法。类似观察者模式
下面的例子通过侦听器监听输入,输出逆向的字符串
<html>
<div id="vue-example-3">
<input type="text" v-model="message">
<p>输出结果:{{result}}</p>
</div>
<script>
new Vue({
el: '#vue-example-3',
data: {
message: '',
result: ''
},
watch: {
// 监听 message 的变化
message: function (newValue, oldValue) {
// 当 message 变化时变更 result
this.result = this.message.split('').reverse().join('')
}
}
});
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25