computed
computed是计算属性的意思,会根据你所依赖的数据动态显示新的计算结果,并且自动缓存。这个值在调用的时候可以当属性一样用, 不需要加括号
举个例子
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]); //根据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>
`
如果不用computed的话,那么methods里面就会放入太多声明式的逻辑,使得代码重复并且逻辑过多,尤其当在页面中使用大量复杂的逻辑表达式处理数据时,会对页面的可维护性造成很大的影响
watch
watch是监听的意思,它更像是data的数据监听回调,如果某个属性变化了,就去执行一个函数的值。这个值可以是值也可以是方法名,或者包含选项的对象,当 data 的数据发生变化时,就会发生一个回调,他有两个参数,一个 newVal (修改后的 data 数据),一个 oldVal(原来的 data 数据)。并且watch提供了两个选项:第一个:immediate表示是否在第一次渲染的时候执行函数。第二个:deep,意思是如果我们监听一个对象,是否要监听这个对象里面的属性的变化
data: {
user: {
email: "xxxxxxxx@qq.com",
nickname: "小白",
phone: "130xxxxxxxx"
},
displayName: ""
},
watch: {
"user.email": {
handler: "changed",
immediate: true // 第一次渲染是也触发 watch
},
"user.nickname": {
handler: "changed",
immediate: true // 第一次渲染是也触发 watch
},
"user.phone": {
handler: "changed",
immediate: true // 第一次渲染是也触发 watch
}
},
template: `
<div>
{{displayName}}
<button @click="user.nickname=undefined">remove nickname</button>
</div>
`,
methods: {
changed() {
console.log(arguments);
const user = this.user;
this.displayName = user.nickname || user.email || user.phone;
}
}
这里如果不写immediate的话,第一次渲染页面时候不会出现任何的内容,因为watch默认第一次渲染的时候是不执行函数的
总结:
- 如果一个数据依赖其他数据,那就适合将这个数据设置为computed
- 如果你需要在某个数据变化时做一些事情,那就适合使用watch来观察这个数据变化