1. computed 计算属性
不需要加(),根据依赖会自动缓存,如果依赖不变,不会重新计算
<li v-for="(name, index) in nameList" :key="index">{{ name }}</li>
...
data(){
return {
username: [
{ familyName: "张", personalName: "三" },
{ familyName: "李", personalName: "四" },
],
}
},
computed: {
nameList() {
return this.username.map((val, index) => {
return val.familyName + val.personalName;
});
},
},
2. watch 监听数据
当数据发生变化,执行对应的回调
选项:deep
为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做。
选项:immediate
在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调:
<span>{{ obj.a }}</span>
<button @click="obj.a = '22222'">改变</button>
...
data(){
return {
obj: {
a: "1111",
},
}
}
watch: {
obj: { // 监听的属性
handler() {
console.log("obj变化了");
},
deep: true, // 表示对该属性是否进行深度监测
},
},
上面例子中obj:{a:'1111'},对于对象是地址引用,只是更改某个属性是不会更改对象的地址,所以对于该对象来说,是没有变化的。如果没有设置deep:true,是不会监听到obj改变
watch是用于监听数据的变化,当某些场景下不想要数据被监听到发生了变化,可以设置标识,如下面例子中的 watchFlag: true
<template>
<div>
<span>{{ num }}</span>
<div>
<button @click="count(1)">+1</button>
<button @click="count(-1)">-1</button>
<button @click="count(2)">+2</button>
<button @click="count(-2)">-2</button>
</div>
<button @click="cancel">撤销</button>
<div>{{ changeRecord }}</div>
</div>
</template>
...
data(){
return {
num: 0,
changeRecord: [],
watchFlag: true,// 设置标记,true时监听
}
},
watch: {
num: {
handler(newVal, oldVal) {
if (this.watchFlag) {
this.changeRecord.push({ from: oldVal, to: newVal });
}
},
},
},
methods:{
count(i) {
this.num += i;
},
cancel() {
if (this.changeRecord.length === 0) return;
let lastRecord = this.changeRecord.pop();
this.watchFlag = false;//由于撤销导致num变化,此时不想被watch,所以设置为false
this.num = lastRecord.from;
this.$nextTick(() => {//由于watch是异步的,底层是根据nextTick实现,所以当watch完成后,就可以立马执行这个nextTick,将标记设置为true
this.watchFlag = true;
});
},
}
上述例子需要注意:
- watch 异步,是通过nextTick实现的
- 当在某些情况下不需要监听时,可以设置一个标记,判断是否监听
- watch中不要使用箭头函数,因为箭头函数中的this未定义,指向外层的对象new Vue({}),实例初始化时,{}这是传的对象,所以箭头函数中的this指向外部的全局对象
<span>{{ test }}</span>
...
data(){
return {
test: "测试",
}
},
watch:{
test(){
console.log('test更新了')
},
immediate: true,//第一次展示页面时,未设置或设置为false,都不会触发;为true会触发
}
3. computed,watch区别
都是监听数据,
其中computed,计算属性,看上去是一个方法,但是在使用时,是当成属性,不需要加();有缓存,当依赖的数据发生变化时,会自动更新,如果没变化,直接读缓存。
watch 检测数据变化时,会执行对应的回调。选项deep为true时,监听对象内部属性的变化,选项immediate为true时,将立即以表达式的当前值触发回调。
computed 常用于 依赖的数据变化后,更新数据;watch主要侧重于,数据变化后,需要做哪些操作