3. 计算属性和侦听器
- 计算属性
- 侦听器
1. 计算属性
虽然在模板中使用 js 表达式,可以一定程度上改变 data 显示的内容,但是如果我们要对 data 的修改做很多的步骤,这个时候,使用 js 表达式就不太好了,因为会导致模板整体非常不清晰。所以这种时候,建议使用计算属性。
在 vue 中,使用 computed 数据选项来添加计算属性。计算属性里面对应的是一个个方法。
方法需要有一个返回值,在模板中就书写方法名。
具体示例如下:
<body>
<div id="app">
<p>{{ message.split('').reverse().join('')}}</p>
<p>{{ reverseWord }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : '#app',
data : {
message : 'this is a test'
},
// 计算属性
computed: {
reverseWord(){
return this.message.split('').reverse().join('');
}
},
})
</script>
</body>
有一个和计算属性非常相似的东西,叫做方法。示例如下:
js 部分
...
// 方法
methods: {
reverseWord2(){
return this.message.split('').reverse().join('');
}
},
...
模板部分
...
<p>{{ reverseWord2() }}</p>
...
两者看起来用法相似,但是在实际的使用中,是有的区别的。
计算属性是只有依赖项发生改变的时候,才会重新进行计算。而方法是在只要有数据发生变化,所有的方法全部重新执行。
<body>
<div id="app">
<button @click="a++">a++</button>
<button @click="b++">b++</button>
<p>计算属性1:{{com1}}</p>
<p>计算属性2:{{com2}}</p>
<p>方法1:{{met1()}}</p>
<p>方法2:{{met2()}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : '#app',
data : {
a : 1,
b : 1
},
computed: {
com1(){
console.log('计算属性 1 被调用');
return this.a;
},
com2(){
console.log('计算属性 2 被调用');
return this.b;
}
},
methods: {
met1(){
console.log('方法 1 被调用');
return this.a;
},
met2(){
console.log('方法 2 被调用');
return this.b;
}
},
})
</script>
</body>
效果:点击按钮 a++,计算属性只有1发生改变,计算属性2不发生改变。但是方法无论是1还是2都会重新执行。
什么时候用计算属性?什么时候用方法?
如果计算的开销很大,那么建议使用计算属性,因为只有依赖的项目发生变化时才重新进行计算。
如果性能开销不大,并且不希望结果缓存,每一次都想得到新的结果,那么就可以使用方法。
计算属性的 setter
一般情况下,我们使用计算属性的 getter 就足够了。因为一般都是获取计算属性的值。但是某些情况下,可能涉及到设置计算属性的值,那么这个时候就需要知道计算属性 setter 的相关知识。
这个时候,计算属性对应的值就应该是一个对象,而不是一个方法。对象里面有 get 和 set 这两个方法。
当我们设置计算属性的值的时候,所设置的值会作为参数自动传入 set 方法里面。
代码示例如下:
<body>
<div id="app">
<p>你的全名为:{{ fullName }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : '#app',
data : {
xing : 'xie',
ming : ' jie'
},
computed: {
fullName: {
get(){
return this.xing + ' ' + this.ming;
},
set(value){
const newName = value.split(' ');
this.xing = newName[0];
this.ming = newName[1];
}
}
},
})
</script>
</body>
2. 侦听器
在 vue 实例上面,提供了一个 $watch 的方法,可以侦听 data 的变化。其实在选项对象中,也有一个 watch 选项。
也可以对数据进行侦听。代码示例如下:
<body>
<div id="app">
<p>{{ name }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : '#app',
data : {
name : 'xiejie'
},
watch: {
name(newValue,oldValue){
console.log('新的值为:',newValue);
console.log('旧的值为:',oldValue);
}
},
})
</script>
</body>
watch 数据选项和 $watch 方法的用法基本一致的。唯一的区别在于 $watch会返回一个方法,该方法可以取消监听。
<body>
<div id="app">
<button @click="a++">+1</button>
<p>{{ a }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el : '#app',
data : {
a : 1
}
})
const unwatch = app.$watch('a',(newVal,oldVal)=>{
console.log('新的值为:',newVal);
console.log('旧的值为:',oldVal);
if(newVal === 5){
unwatch();
}
});
</script>
</body>