计算属性
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。所以我们需要使用计算属性。
在vue3中时可以使用vue2的方式编写计算属性的,但是不建议。
计算属性编写格式
- vue3中把计算属性变成了一个组合式的API,使用的时候需要从vue中引入,然后再setup中进行配置。
- vue3中的计算属性仍然有两种写法,简写和全写。全写有
get和set
方法,简写是如果计算属性只有get方法可以进行简写 - 计算属性中get的返回值是一个
计算属性 ref
。和其他一般的 ref 类似,你可以通过.value
访问计算结果,下面的示例中就可以通过fullName.value
访问计算结果,同时计算属性可以在模板中自动解包,因此在模板表达式中引用使无需添加.value
。
import { computed } from 'vue'
setup() {
// 计算属性——简写
let fullName = computed(() => {
return
})
// 计算属性——全写
let fullName = computed(() => {
get(){
return
},
set(value){
}
})
return {
fullName
}
}
计算属性例子
实现效果:
App.vue:
<template>
<demo/>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
name: 'AppVue',
components: { Demo },
}
</script>
Demo.vue
<template>
<h1>Demo组件</h1>
姓:<input type="text" v-model="person.firstName" />
<br />
名:<input type="text" v-model="person.lastName" />
<br />
<span>全名:{{person.fullName}}</span>
<br />
全名(可改):<input type="text" v-model="person.fullNameChange" />
</template>
<script>
import { reactive,computed } from 'vue'
export default {
name: 'DemoVue',
// vue2实现
/* computed:{
fullName(){
return this.person.firstName+"-"+this.person.lastName
}
},*/
setup() {
// 数据
let person = reactive({
firstName: '张',
lastName: '三',
})
// 计算属性
// 计算属性-简写(没有考虑计算属性被修改的情况,只有get方法时)
person.fullName = computed(() => {
return person.firstName+"-"+person.lastName
})
// 计算属性-完整(计算属性可以被修改)
// 现在当你再运行 person.fullNameChange = 'John Doe' 时,setter 会被调用而 firstName 和 lastName 会随之更新。
person.fullNameChange = computed({
get(){
return person.firstName + "-" + person.lastName
},
set(value){
const nameArr = value.split("-")
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
return {
person,
}
}
}
</script>
计算属性和方法的比较——computed的缓存
我们在表达式中像这样调用一个函数也会获得和计算属性相同的结果。
使用方法:
//模板
<p>{{ calculateBooksMessage() }}</p>
//setup
function calculateBooksMessage() {
return author.books.length > 0 ? 'Yes' : 'No'
}
使用计算属性:
//模板
<span>{{ publishedBooksMessage }}</span>
//setup
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
两种方式在计算结果上完全一致,不同之处在于计算属性值会基于其响应式依赖被缓存
:
- 一个计算属性仅会在其
响应式依赖更新时才重新计算
,并且将更新后的结果缓存起来。这意味着只要author.books
不改变,无论多少次访问publishedBooksMessage
都会立即返回先前的计算结果
,而不用重复执行 getter 函数。 - 方法调用总是会在
重渲染
发生时再次执行函数
所以计算属性可以提升程序性能,优化渲染速度。
计算属性的只读性
从计算属性返回的值是派生状态。
可以把它看作是一个“临时快照
”,每当源状态发生变化时,就会创建一个新的快照。更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。
计算属性只进行计算操作
计算属性的 getter 应只做计算而没有任何其他的副作用。举例来说,不要改变其他状态
、在 getter 中做异步请求
或者更改 DOM
。