一、什么是计算属性:
computed函数,是用来定义计算属性的,计算属性不能修改。
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。
计算属性还可以依赖多个Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。
二、computed运行原理
computed的属性是动态挂载到vm实例上的,和普通的响应式数据在data里声明不同
设置computed的getter,如果执行了computed对应的函数,由于函数会读取data属性值,因此又会触发data属性值的getter函数,在这个执行过程中就可以处理computed相对于data的依赖收集关系了
首次计算computed的值时,会执行vm.computed属性对应的getter函数(用户指定的computed函数,如果没有设置getter,那么将当前指定的函数赋值computed属性的getter),进行上述的依赖收集
如果computed的属性值又依赖了其他computed计算属性值,那么会将当前target暂存到栈中,先进行其他computed计算属性值的依赖收集,等其他计算属性依赖收集完成后,在从栈中pop出来,继续进行当前computed的依赖收集
三、vue2的写法
代码如下(示例):
<template>
<h1>一个人的信息</h1>
姓:<input type="text" v-model="person.firstName">
<br>
名:<input type="text" v-model="person.lastName">
<br>
<span>全名:{{fullname}}</span>
<br>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'Demo',
computed:{
fullname(){
return this.person.firstName+"-"+this.person.lastName
}
},
setup(){
//数据
let person = reactive({
firstName:'张',
lastName:'三'
})
//返回一个对象(常用)
return {
person
}
}
}
</script>
vue3的写法
<template>
<h1>一个人的信息</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.fullName">
</template>
<script>
import {reactive,computed} from 'vue'
export default {
name: 'Demo',
setup(){
//数据
let person = reactive({
firstName:'张',
lastName:'三'
})
//计算属性——简写(没有考虑计算属性被修改的情况)
person.fullName = computed(()=>{
return person.firstName + '-' + person.lastName
})
//计算属性——完整写法(考虑读和写)
// person.fullName = computed({
// get(){
// return person.firstName + '-' + person.lastName
// },
// set(value){
// const nameArr = value.split('-')
// person.firstName = nameArr[0]
// person.lastName = nameArr[1]
// }
// })
//返回一个对象(常用)
return {
person
}
}
}
</script>
data 属性初始化 getter setter
computed 计算属性初始化,提供的函数将用作属性 vm.fullName 的 getter
当首次获取 fullName 计算属性的值时,Dep 开始依赖收集
在执行 message getter 方法时,如果 Dep 处于依赖收集状态,则判定firstName和lastName为fullName 的依赖,并建立依赖关系
当firstName或lastName 发生变化时,根据依赖关系,触发 fullName 的重新计算
如果计算值没有发生变化,不会触发视图更新
总结
通过以上的分析,我们知道计算属性本质上就是一个 computed watcher,也了解了它的创建过程和被访问触发 getter 以及依赖更新的过程,其实这是最新的计算属性的实现,之所以这么设计是因为 Vue 想确保不仅仅是计算属性依赖的值发生变化,而是当计算属性最终计算的值发生变化才会触发渲染 watcher 重新渲染,本质上是一种优化。
注:现在有两个computed计算值,其中一个computed计算值为什么可以依赖另外一个computed计算值?
在Vue 3中,computed属性可以依赖其他的computed属性。这是因为Vue 3使用了新的响应式系统,它能够更好地追踪数据的依赖关系。当一个组件中存在多个computed属性时,每个computed都会根据其自己的依赖进行计算,并且当任何一个依赖发生变化时,该computed也会相应地重新计算其值。
这种方式方便了开发者编写可读性更高,依赖关系更清晰的代码。