Vue的computed和watch
computed(计算属性)
用途
被计算出来的属性就是计算属性
代码示例
// 引用完整版 Vue,方便讲解
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data: {
user: {
email: "122322323@qq.com",
nickName: "jack",
phone: "13812312312"
}
},
computed: {
displayName: {
get() {
const user = this.user;
return user.nickname || user.email || user.phone;
},
set(value) {
console.log(value);
this.user.nickname = value;
}
}
},
// DRY don't repeat yourself
// 不如用 computed 来计算 displayName
template: `
<div>
{{displayName}}
<div>
{{displayName}}
<button @click="add">set</button>
</div>
</div>
`,
methods: {
add() {
console.log("add");
this.displayName = "圆圆";
}
}
}).$mount("#app");
缓存
- 如果依赖的缓存没有变化,就不会重新计算
- getter/setter默认不做缓存,Vue做了特殊处理
watch(监听)
用途
- 当数据发送变化时,执行一个函数
代码示例
import Vue from "vue/dist/vue.js";
Vue.config.productionTip = false;
new Vue({
data: {
n: 0,
history: [],
inUndoMode: false
},
watch: {
n: function (newV, oldV) {
console.log(this.inUndoMode);
if (!this.inUndoMode) {
this.history.push({ from: oldV, to: newV });
}
}
},
// 不如用 computed 来计算 displayName
template: `
<div>
{{n}}
<hr />
<button @click="add1">+1</button>
<button @click="add2">+2</button>
<button @click="minus1">-1</button>
<button @click="minus2">-2</button>
<hr/>
<button @click="undo">撤销</button>
<hr/>
{{history}}
</div>
`,
methods: {
add1() {
this.n += 1;
},
add2() {
this.n += 2;
},
minus1() {
this.n -= 1;
},
minus2() {
this.n -= 2;
},
undo() {
const last = this.history.pop();
this.inUndoMode = true;
console.log("ha" + this.inUndoMode);
const old = last.from;
this.n = old; // watch n 的函数会异步调用
this.$nextTick(() => {
this.inUndoMode = false;
});
}
}
});
immediate和handler的用法
这样使用watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性
new Vue({
el: '#root',
data: {
cityName: ''
},
watch: {
cityName: {
handler(newName, oldName) {
// ... },
immediate: true
}
}
})
deep
- 可以理解为深拷贝
- 如果只是监听对象的话,deep就设置为false
- 如果要监听对象里面的属性变化,deep就设置为true
new Vue({
el: '#root',
data: {
cityName: {id: 1, name: 'shanghai'}
},
watch: {
cityName: {
handler(newName, oldName) { // ... },
deep: true,
immediate: true
}
}
})