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来观察这个数据变化