由数据响应式我们知道,Vue会在data变化时更新UI。
那么data变化时,除了更新UI之外,还可以做点什么?
computed:计算属性
就是由其他属性计算得来的属性
例1:展示用户名
new Vue({
data: {
user: {
email: "1234567@qq.com",
nickname: "小七",
phone: "13812312312"
}
},
template: `
<div>
{{user.nickname || user.email || user.phone}}
</div>
`,
}).$mount("#app");
需求:div里展示用户的昵称。
可是,用户有可能没填昵称,所以就优先展示昵称,如果没有昵称,就展示email,没有email,就展示电话号。
问题是,如果有一百个用户,这句代码就要重复一百次。重复的缺点是,如果有一天需求变了,要你优先展示email,你就要改一百个地方。
computed的函数形式
所以,不如使用计算属性:
computed:{
displayName(){
const user=this.user
return user.nickname || user.email || user.phone
}
},
template: `
<div>
{{displayName}}
</div>
`,
displayName以函数的形式定义,在div里展示displayName,直接以属性的形式调用,不需要加括号。会默认读取它的返回值。
computed:使由其他属性计算而来的属性成为一个属性
我能不能设置计算属性呢?比如点击按钮,就改变昵称。
设getter,setter
computed: {
displayName: {
get() {
const user = this.user;
return user.nickname || user.email || user.phone;
},
set(val) {
this.user.nickname = val;
}
}
},
template: `
<div>
{{displayName}}
<button @click="displayName='小八'">set</button>
</div>
`,
displayName改为对象形式,里边定义get(){},set(){}函数。
如果直接展示:{{displayName}},就会调用get函数。
set函数会把val赋给data里的用户对象。点击按钮,会执行:displayName='小八'。页面中的昵称就会更新。
例2:列表按需展示
页面中有三个按钮,点击‘全部’,显示全部用户;点击‘男’,只显示男性用户。。。
let id = 0;
const createUser = (name, gender) => {
id += 1;
return { id: id, name: name, gender: gender };
};
new Vue({
data() {
return {
users: [
createUser("小四", "男"),
createUser("小五", "女"),
createUser("小六", "男"),
createUser("小七", "女")
],
gender: ""
};
},
computed: {
displayUsers() {
const { users, gender } = this;
const hash={
'male':"男",
"female":'女'
}
if (gender === "") {
return users;
} else if (gender === "male" || gender === "female") {
return users.filter(u => u.gender === hash[gender]);
}
}
},
template: `
<div>
<div>
<button @click='gender = ""'>全部</button>
<button @click='gender = "male"'>男</button>
<button @click='gender = "female"'>女</button></div>
<ul>
<li v-for="(u,index) in displayUsers" :key="index">{{u.name}} - {{u.gender}}</li>
</ul>
</div>
`
}).$mount("#app");
点击‘全部’:


通过计算属性displayUsers来完成。我们的需求是根据不同的gender,展示不同的用户。所以就是根据users和gender得到不同的结果,就是通过其他属性计算别的属性。
计算属性里,根据不同的gender,返回各自的结果。template里根据这个计算属性的返回值展示用户数组。然后点击按钮时,只需要改变gender就可以。至于改变完gender之后,如何展示不同的结果,就是计算属性的任务了。
所以计算属性的使用可以使代码逻辑很清晰。
缓存
如果计算属性依赖的属性没有发生变化,那么这个计算属性就不会重新计算。
以2为例,我在displayUsers里第一句加console.log。点击男,有打印值。再点一次男,发现没有打印值了。说明,计算属性没有执行。displayUsers依赖users,gender两个属性,再次点击男时,发现他俩都没变,那就不会再计算一次。
(缓存原理没有)