先贴一下官方译名:
computed:计算属性
watch:侦听属性
methods:方法
<template>
<div id="calTest">
{{num}}
{{num1()}}
{{msg}}
<button @click="changeMsg">change msg</button>
<button @click="changeName">change name</button>
</div>
</template>
<script>
export default {
data() {
return {
name: "betty",
msg: 100
};
},
computed: {
num() {
let res = this.name + "!";
console.log("do computed");
return res;
}
},
methods: {
num1() {
let res = this.name + "!";
console.log("do methods");
return res;
},
changeMsg() {
this.msg += 1;
},
changeName() {
this.name = "alan";
}
}
};
</script>
这是一个 computed 和 methods 比较使用的例子,我们可以很清楚的看到相似与不同:
相同之处就是用 computed 和 methods 返回的结果都是一样的
不同在于,在模板中computed 直接作为变量调用,而 methods 要写成方法调用(即加上括号);
再有,例子中的 msg 是一个独立的数据,用一个button控制值的改变,这么做是为了看出 computed 和 methods 的关键性差别:
computed 有缓存,只有依赖数据变化才重新计算,而 methods 在每次视图渲染时都会执行。当我们点击 changeMsg 按钮时,computed是不会执行的,而methods 的 num1 方法会执行,只有我们在点击 changeName 按钮时(即num的依赖数据name的值发生了改变),computed 会执行(当然methods num1也会执行)
<script>
export default {
data() {
return {
a: 1,
b: 2,
c: { c1: 6 },
d: 4,
e: {
f: {
g: 5
}
}
};
},
watch: {
a: function(val, oldVal) {
console.log(val, oldVal);
},
b: "someMethod",
c: {
handler: function(val, oldVal) {
console.log(val, oldVal);
},
deep: true
},
d: {
handler: "someMethod",
immediate: true
},
"e.f": function(val, oldVal) {
console.log(val, oldVal);
}
},
methods: {
someMethod() {
console.log("somemethods");
}
}
};
</script>
c 如果不加 deep 的话,c1 的值变动的时候是监听不到的,加了 deep 无论嵌套多深都能监听,val 和 oldVal 都是返回 {ob: Observer} 对象
d 回调会在侦听开始之后被立即调用
e.f 也是返回 {ob: Observer} 对象,这里要注意一点,在用 Vue Devtools 修改 c 和 e.f 的值的时候,不要去修改c1 / g 的值,而是要修改 c 和 e.f 的值,否则会出现 val 和 oldVal 都是新值的情况
可以看到,watch 里的对象,key是需要侦听的数据的名字,value是回调函数/方法名...
注意:watch的回调函数不要用箭头函数
那么,computed 和 watch 的区别又是什么呢?
其实官方文档已经很好地把二者适用的场景描述了出来:
computed : 减少模板中的逻辑,快速计算更新视图中的值
watch : 虽然在大多数的情况下computed更合适,但有时也需要一个自定义的侦听器。在数据变化时执行异步操作或者开销比较大的操作时,用watch