前言:
模板中的表达式虽然方便,但也只能用来做简单的操作;如果在模板中写太多逻辑,会让模板变得臃肿,难以维护;因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑
- 选项式 API 中,可以提供computed选项来声明计算属性
- 组合式 API 中,可以通过computed回调函数返回的值来声明计算属性
计算属性【选项式】
<script>
export default {
data: () => ({
age: 20, // 年龄
birthday: '' // 生日
}),
// 计算属性选项
computed: {
// 年龄阶段
ageState() {
if (this.age < 18) {
return '未成年'
} else if (this.age < 35) {
return '青年'
} else if (this.age < 50) {
return '中年'
} else {
return '老年'
}
},
// 星座
constellation() {
// yyyy-MM-dd -> ['yyyy', 'MM', 'dd']
let birArr = this.birthday.split('-')
// 月份
let month = parseInt(birArr[1])
// 日份
let day = parseInt(birArr[2])
// 判断
switch (month) {
case 1:
if (day <= 19) {
return '魔羯座'
} else {
return '水平座'
}
case 2:
if (day <= 18) {
return '水平座'
} else {
return '双鱼座'
}
case 3:
if (day <= 20) {
return '双鱼座'
} else {
return '白羊座'
}
case 4:
if (day <= 19) {
return '白羊座'
} else {
return '金牛座'
}
case 5:
if (day <= 20) {
return '金牛座'
} else {
return '双子座'
}
case 6:
if (day <= 21) {
return '双子座'
} else {
return '巨蟹座'
}
case 7:
if (day <= 22) {
return '巨蟹座'
} else {
return '狮子座'
}
case 8:
if (day <= 22) {
return '狮子座'
} else {
return '处女座'
}
case 9:
if (day <= 22) {
return '处女座'
} else {
return '天秤座'
}
case 10:
if (day <= 23) {
return '天秤座'
} else {
return '天蝎座'
}
case 11:
if (day <= 22) {
return '天蝎座'
} else {
return '射手座'
}
case 12:
if (day <= 21) {
return '射手座'
} else {
return '魔羯座'
}
default:
return '请选择日期'
}
}
}
}
</script>
<template>
<div>
年龄:<input type="number" v-model.lazy="age">
<!-- 简单的表达式 -->
<h3>年龄阶段(简单):{{ age < 18 ? '未成年' : '成年' }} </h3>
<!-- 计算属性:年龄阶段 -->
<h3>年龄阶段(复杂):{{ ageState }} </h3>
</div>
<hr>
<div>
生日:<input type="date" v-model="birthday">
<!-- 计算属性:星座 -->
<h3>星座:{{ constellation }}</h3>
</div>
</template>
计算属性【组合式】
<script setup>
import { computed, ref } from 'vue'
let age = ref(20) // 年龄
// 计算属性:年龄阶段
let ageState = computed(() => {
if (age.value < 18) {
return '未成年'
} else if (age.value < 35) {
return '青年'
} else if (age.value < 50) {
return '中年'
} else {
return '老年'
}
})
let birthday = ref('') // 生日
// 计算属性:星座
let constellation = computed(() => {
// yyyy-MM-dd -> ['yyyy', 'MM', 'dd']
let birArr = birthday.value.split('-')
// 月份
let month = parseInt(birArr[1])
// 日份
let day = parseInt(birArr[2])
// 判断
switch (month) {
case 1:
if (day <= 19) {
return '魔羯座'
} else {
return '水平座'
}
case 2:
if (day <= 18) {
return '水平座'
} else {
return '双鱼座'
}
case 3:
if (day <= 20) {
return '双鱼座'
} else {
return '白羊座'
}
case 4:
if (day <= 19) {
return '白羊座'
} else {
return '金牛座'
}
case 5:
if (day <= 20) {
return '金牛座'
} else {
return '双子座'
}
case 6:
if (day <= 21) {
return '双子座'
} else {
return '巨蟹座'
}
case 7:
if (day <= 22) {
return '巨蟹座'
} else {
return '狮子座'
}
case 8:
if (day <= 22) {
return '狮子座'
} else {
return '处女座'
}
case 9:
if (day <= 22) {
return '处女座'
} else {
return '天秤座'
}
case 10:
if (day <= 23) {
return '天秤座'
} else {
return '天蝎座'
}
case 11:
if (day <= 22) {
return '天蝎座'
} else {
return '射手座'
}
case 12:
if (day <= 21) {
return '射手座'
} else {
return '魔羯座'
}
default:
return '请选择日期'
}
})
</script>
<template>
<div>
年龄:<input type="number" v-model.lazy="age">
<!-- 简单的表达式 -->
<h3>年龄阶段(简单):{{ age < 18 ? '未成年' : '成年' }} </h3>
<!-- 计算属性 -->
<h3>年龄阶段(复杂):{{ ageState }} </h3>
</div>
<hr>
<div>
生日:<input type="date" v-model="birthday">
<h3>星座:{{ constellation }}</h3>
</div>
</template>
计算属性与方法的区别:
● 两种方式在结果上确实是完全相同的,不同之处在于计算属性值会基于其响应式依赖被缓存。
● 一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要所依赖的数据源不改变,无论多少次访问计算属性都会立即返回先前的计算结果,而不用重复执行getter函数。
● 方法调用总是会在重新渲染发生时再次执行函数。
计算属性注意事项:
● 不要在计算函数中做异步请求或者更改DOM
● 避免直接修改计算属性值