参考:https://blog.csdn.net/weixin_53312997/article/details/127606312
computed
此处的 已有属性 指的就是 data或者props中的属性
methods 和 computed 的区别
methods :getFullName()每调用一次,就会执行一次getFullName方法;
computed :fullName每调用一次,会先观察 firstName 和 lstName 的值有没有改变,如果两个都没变,则不会执行fullName;若其中一个发生变化了,才会执行fullName;因为vue内部对computed 是有缓存的;
总结:computed 的性能更好,建议使用computed
watch和 computed 的区别
watch可以开启异步任务,computed不能开启异步任务
假如在watch中开启异步任务:
<template>
<div class="profile">
<div>profile</div>
<br><br>
<input v-model="firtName"/>
<br><br>
<input v-model="lastName"/>
<h1>{{fullName}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
firtName: '张',
lastName: '三',
fullName: '张山'
}
},
watch: {
firtName() {
setTimeout(() => {
this.fullName = this.firtName + this.lastName
}, 1000);
}
}
}
</script>
在第一个input中输入1,一秒钟后结果如下图:
假如在computed中开启异步任务:
<template>
<div class="profile">
<div>profile</div>
<br><br>
<input v-model="firtName"/>
<br><br>
<input v-model="lastName"/>
<h1>{{fullName}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
firtName: '张',
lastName: '三',
}
},
computed: {
fullName() {
setTimeout(() => {
return this.firtName + this.lastName
},1000)
}
}
}
</script>
在第一个input中输入1,一秒钟后结果如下图:
解析:仔细看computed中的fullName(), 发现fullName()是没有返回值的;return this.firtName + this.lastName 是箭头函数的返回值,所以{{fullName}}处没有值;
因为computed是需要返回值的,所以不能操作异步任务。
当watch和computed都能实现时,建议采用computed
watch实现搜索功能:
<template>
<div class="profile">
<input v-model="keyWord"/>
<div v-for="person in filPersons" :key=person.id>{{person.name}} - {{person.age}}</div>
</div>
</template>
<script>
export default {
data() {
return {
keyWord: '',
persons: [
{id: '001', name: '马冬梅', age: 18},
{id: '002', name: '周冬雨', age: 20},
{id: '003', name: '周杰伦', age: 25},
{id: '004', name: '温兆伦', age: 29},
],
filPersons: []
}
},
watch: {
keyWord: {
immediate: true,//在beforeCreate()前就调用一次handler,使this.filPersons获取到persons的初始值
handler(newValue) {
console.log('123456'.indexOf(''));//0
this.filPersons = this.persons.filter((p) => {
return p.name.indexOf(newValue) != -1
})
}
}
}
}
</script>
computed实现搜索功能:
<template>
<div class="profile">
<input v-model="keyWord"/>
<div v-for="person in filPersons" :key='person.id'>{{person.name}} - {{person.age}}</div>
</div>
</template>
<script>
export default {
data() {
return {
keyWord: '',
persons: [
{id: '001', name: '马冬梅', age: 18},
{id: '002', name: '周冬雨', age: 20},
{id: '003', name: '周杰伦', age: 25},
{id: '004', name: '温兆伦', age: 29},
]
}
},
computed: {
//computed在created()后会执行一次;当keyWord变化时也会执行
filPersons() {
return this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) != -1
})
}
}
}
</script>
可证:当watch和computed都能实现时,建议采用computed,computed更简洁。
computed小练习:
<template>
<div class="profile">
<input v-model="keyWord"/>
<button @click="sortType = 1">年龄升序</button>
<button @click="sortType = 2">年龄降序</button>
<button @click="sortType = 0">年龄原序</button>
<div v-for="person in filPersons" :key='person.id'>{{person.name}} - {{person.age}}</div>
</div>
</template>
<script>
export default {
data() {
return {
keyWord: '',
sortType: 0,//0原顺序,1升序,2降序
persons: [
{id: '001', name: '马冬梅', age: 40},
{id: '002', name: '周冬雨', age: 20},
{id: '003', name: '周杰伦', age: 25},
{id: '004', name: '温兆伦', age: 29},
]
}
},
computed: {
//computed在created()后会执行一次;当keyWord变化时也会执行
filPersons() {
let arr = this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) != -1
})
if(this.sortType) {
// 当this.sortType不为0时
arr.sort((p1, p2) => {
return this.sortType == 1 ? p1.age-p2.age : p2.age-p1.age
})
}
return arr
}
}
}
</script>
点击“年龄升序”