1. computed
computed
即计算的意思,是创建 vue实例
中的计算属性,属性值为一个对象,对象里面是各种计算得来的数据变量,和 data
属性里面的变量一样
也就是说该属性用于存放计算得来的各种属性,并且如果该计算属性依赖的属性没有发生变化就不会重新触发计算。
以下小例来自 vue 官网
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4 是属性调用,不是函数调用
2. watch
watche
即监听的意思,是对 data
属性中的各种数据进行监听的,会在监听的数据发生变化时自动调用对应的监听函数,因此监听的属性是 data
里的数据,属性值是相关的操作。如下所示:
new Vue({
data: {
n: 1,
obj: {
a: "a"
},
e: 2
},
watch:{
n: function (newVal, oldVal) {
console.log(`a变化了,由${oldVal}变成了${newVal}`)
},
obj() {
console.log("obj 变了");
},
"obj.a": function() {
console.log("obj.a 变了");
},//属性名有特殊符号 . 因此必须用引号括起来
e: [
'handle1',
function handle2 (val, oldVal){
/do something
}
] //数组的放置依次执行多个函数操作
}
})
immediate: true
在 watch
里面的函数是只有在数据变化时才会被自动调用,因此在数据初始化刚开始出现在页面时是不会执行 watch
里的监听回调的,因此若想在数据在初始化时就立即被调用,则要自行设置如下:
new Vue({
data:{
c: 4
},
watch:{
handler: 'someMethod', //处理函数可以是 methods 里的方法名
immediate: true //将这一个属性设置为 true,表示立即调用
}
})
deep: true
当一个对象的内部属性发生变化时,默认该属性不会被认为发生变化,因为用到是 ===
操作符来判断的是否改变,而对象内部数据改变但地址没有改变,因此在比较仅改变对象内部数据时前后对象是比较的地址,结果是 obj 没有改变,就只会调用内部属性的监听函数,而不会调用其所在对象的监听函数,如下所示:
new Vue({
data: {
obj: {
a: "a"
}
},
watch:{
obj() {
console.log("obj 变了");
},
"obj.a": function() {
console.log("obj.a 变了");
},//属性名有特殊符号 . 因此必须用引号括起来
},
template: `
<div>
//按钮点击只会输出 obj.a 变了,而不会输出 obj 变了
<button @click="obj.a += 'hi'">obj.a + 'hi'</button>
//由于改变了整个对象,整个对象里面的都会被改变,输出 obj.a 变了,obj 变了
<button @click="obj = {a:'a'}">obj = 新对象</button>
</div>
`
})
因此若想当对象内如数据改变时认为对象也改变了,触发对象的监听函数,则可在对象的监听事件中加上一句 deep: true
,表示往深了看,用于复杂类型的深度监听,用如下方法:
watch:{
obj: {
handler:function(){
console.log("obj 变了");
},
deep: true //默认是 false
}
}
3. 二者的区别
1. 分别是什么
computed
是计算属性,是 data
属性的扩展,用于存放基于 data
数据经过各种计算得来的属性,有依赖,有缓存,当其所依赖的数据发生变化时 computed
会重新计算
watch
是监听属性,是对 data
中各种数据的监听,在数据变化时做出相应处理。
2. 调用过程
computed
是会产生新的数据属性,并对其进行监听计算。
watch
只是单纯地对当前数据进行监听处理,不会产生新的数据属性。