字面上的区别
computed
是计算属性,它会根据你所依赖的数据动态显示新的计算结果watch
是一个对data
的数据监听回调, 当依赖的data
的数据变化时, 会执行一个回调函数。在回调中会传入newVal
和oldVal
两个参数。
各自的作用
computed
new Vue({
el: '#app',
data: {
message: 'hello'
},
template: `
<div>
<p>原始字符串: "{{ message }}"</p>
<p>反转字符串: "{{ computedMessage}}"</p>
</div>
`,
computed: {
// 计算属性的 getter
computedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
// 原始字符串: "hello"
// 反转字符串: "olleh"
computedMessage
的值由 message.split('').reverse().join('')
计算得到,computedMessage
使用时不需要加括号,可以直接作为属性使用,展示在页面中
let id = 0;
const createUser = (name, gender) => {
id += 1;
return { id: id, name: name, gender: gender };
};
new Vue({
data() {
return {
users: [
createUser("方方", "男"),
createUser("圆圆", "女"),
createUser("小新", "男"),
createUser("小葵", "女")
],
gender: ""
};
},
computed: {
displayUsers() {
const hash = {
male: "男",
female: "女"
};
const { users, gender } = this;
if (gender === "") {
return users;
} else if (typeof gender === "string") {
return users.filter(u => u.gender === hash[gender]);
} else {
throw new Error("gender 的值是意外的值");
}
}
},
methods: {
setGender(string) {
this.gender = string;
}
},
template: `
<div>
<div>
<button @click="setGender('') ">全部</button>
<button @click="setGender('male')">男</button>
<button @click="setGender('female')">女</button>
</div>
<ul>
<li v-for="(u,index) in displayUsers" :key="index">
{{u.name}} - {{u.gender}}
</li>
</ul>
</div>
`
}).$mount("#app");
点击不同的按钮时,计算结果发生变化,重新计算后页面更新。
计算属性的结果会被缓存,并且计算属性只有在它的相关依赖发生改变时才会重新计算。所以再次点击相同按钮时,由于计算结果不变,就不会重新计算。
watch
-
当数据变化时执行一个函数
-
watch
属性可以是字符串、函数、对象、数组 -
拥有
deep
,immediate
属性
new Vue({
data: {
n: 0,
obj: {
a: "a"
}
},
template: `
<div>
<button @click="n += 1">n+1</button>
<button @click="obj.a += 'hi'">obj.a + 'hi'</button>
<button @click="obj = {a:'a'}">obj = 新对象</button>
</div>
`,
watch: {
n() {
console.log("n 变了");
},
obj() {
console.log("obj 变了");
},
"obj.a": function() {
console.log("obj.a 变了");
}
}
}).$mount("#app");
// 点击 "n+1" , 得 "n 变了"
// 点击 "obj.a+hi" , 得 "obj.a 变了"
// 点击 "obj=新对象" , 得 "obj 变了"
-
注意:
obj.a
变化时,obj
并没有发生改变;obj
变化时,obj.a
也没有发生改变 -
推测:
watch
的监听方式是——简单数据类型看值,复杂数据类型(对象)看地址
deep
- 那如果想通过监听
obj
,也能发现obj.a
的变化,可以实现吗?
// 使用 deep 可以实现
watch: {
n() {
console.log("n 变了");
},
obj: {
handler(){
console.log("obj 变了");
},
deep: true
},
"obj.a": function() {
console.log("obj.a 变了");
}
}
}).$mount("#app");
// 点击 "obj=新对象" , 得 "obj 变了"、"obj.a 变了"
immediate
在选项参数中指定 immediate: true
将立即以表达式的当前值触发回调
总结
-
如果一个数据依赖于其他数据,那么把这个数据设计为
computed
的 -
如果需要在某个数据变化时做一些事情,使用
watch
来观察这个数据变化
补: watch
可以执行异步而 computed
不行
本文参考摘录了: