1. computed 计算属性
计算属性就是被计算出来的属性就叫计算属性。
new Vue({
data: {
user: {
email: "1",
nickname: "2",
phone: "3"
}
},
template:`
<div>
{{user.nickname || user.email || user.phone}}
</div>
`
}).$mount('#app');
以上代码实现在网页中昵称、邮箱、号码依次优先展示。但如果在网页中有多处展示相同内容的地方,重复使用{{user.nickname || user.email || user.phone}}
并不方便,且不利于统一处理。
于是使用computed。
new Vue({
data: {
user: {
email: "1",
nickname: "2",
phone: "3"
}
},
computed:{
displayName(){
const user = this.user,
return user.nickname || user.email || user.phone
}
},
template:`
<div>
{{displayName}}
</div>
`
}).$mount('#app');
多处使用,统一使用displayName这一计算属性即可。
再给displayName添加getter和setter
computed: {
displayName: {
get() {
const user = this.user;
return user.nickname || user.email || user.phone;
},
set(value) {
this.user.nickname = value;
}
}
}
关于计算属性的缓存
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。如果依赖的属性没有变化,就不会重新计算,getter/setter默认不会做缓存,Vue做了特殊处理。
2. watch 侦听
watch用于在数据变化时,执行一个函数。
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 = {a:'a'}
时,即obj指向一个新的对象,而新对象中的a属性与原来的对象的a属性值相同,于是侦听到obj发生了改变,而obj.a不变。
总结起来就是简单类型进行值的比较,复杂类型进行所保存的地址的比较。
watch的两个参数:
-
deep
deep为true表示该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深。
若以上代码进行修改
watch:{ obj() { handler:{console.log("obj 变了");}, deep: true }, }
则执行
obj.a += 'hi'
时,由于obj中的a属性的值发生了变化,所以obj也被视为发生了改变。 -
immediate
immediate为true表示该回调将会在侦听开始之后被立即调用。默认为false,当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行,设置为true则首次绑定时也执行函数。
3. computed与watch
computed根据你所依赖的数据动态显示新的计算结果,计算结果会被缓存。
watch所监听的data的数据发生变化,便执行回调,在方法中会传入 newVal 和 oldVal。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。如果你需要在某个数据变化时做一些事情,使用watch。
当你有一些数据需要随着其它数据变动而变动时,很容易滥用 watch,这时候应该使用computed计算属性。