计算属性的概念
-
本质:函数 (必须有返回值)| 对象(带getter和setter)
-
解决问题: 模板中过多的逻辑会让模板过重且难以维护,计算属性就是处理这种复杂逻辑的
-
原理: 当依赖的数据发生变化时,计算属性的值会自动更新,与之相关的DOM部分也同步更新
-
理解: 通过一系列运算之后,最终得到一个属性值
-
特点:
- 数据可以进行逻辑处理,减少模板中计算逻辑
- 对依赖的数据进行监视
- 依赖响应式数据
-
运用:
- 定义时要被定义为方法
- 使用计算属性时,当普通属性使用即可
- 在模板结构或
methods方法使用
函数类型
<h1>{{fullName}}</h1>
data(){
return {
firstName: 'Lebron',
lastName: 'James'
}
},
computed: {
fullName(){
return `${this.firstName}·${this.lastName}`
}
}
Vue知道fullName依赖于firstName和lastName,当两者之一发生改变时,所有依赖fullName的绑定也会更新
注意:计算属性的值不能在组件的
props和data中定义
计算属性可以使用箭头函数吗?
this指向谁?
this指向undefined
computed: {
fullName:()=>{ console.log(this) } // 输出undefined
}
- 可以通过函数的内置参数访问
this
computed: {
fullName:(vm)=>`${vm.firstName}·${vm.lastName}` // vm就是当前组件实例
}
对象类型
- 对象类型的计算属性由两部分组成
get()和set(), 分别用来获取计算属性和设置计算属性
getter
- 根据其它依赖属性动态计算当前属性值 (获取计算属性)
- 默认情况下只有
getter
<h1>{{fullName}}</h1>
data(){
return {
firstName: 'Lebron',
lastName: 'James'
}
},
computed: {
fullName:{
get(){
return `${this.firstName}·${this.lastName}`
}
}
}
setter
setter需要自行添加- 不是直接修改计算属性,而是修改它的依赖数据
computed: {
fullName:{
get(){
return `${this.firstName}·${this.lastName}`
},
set(newVal){
console.log(newVal); // 新值是当前修改后的值
}
}
}
为什么模板中的值没发生变化?
- 因为
fullName依赖的数据并没发生变化 - 只有修改其依赖的数据,计算属性才会动态更改
computed: {
fullName:{
get(){
return `${this.firstName}·${this.lastName}`
},
set(newVal){
const newName = newVal.split('·')
this.firstName = newName[0]
this.lastName = newName[1]
}
}
}
计算属性缓存
-
将同一函数定义为一个
methods和一个computed,两种方式的结果是完全不同 -
计算属性与方法的差异: 计算属性可以基于响应式依赖进行缓存,而
methods不会缓存- 只有相关响应式依赖发生改变,
computed才会重新求值
- 只有相关响应式依赖发生改变,
示例:
- 使用
methods进行更改数据,可以看到getFullName方法会被调用 4 次
<h1>{{getFullName()}}</h1>
<h1>{{getFullName()}}</h1>
<h1>{{getFullName()}}</h1>
<h1>{{getFullName()}}</h1>
methods:{
getFullName(){
console.log('执行');
return `${this.firstName}·${this.lastName}`
}
}
- 使用计算属性进行改写数据,方法只调用一次
<h1>{{fullName}}</h1>
<h1>{{fullName}}</h1>
<h1>{{fullName}}</h1>
<h1>{{fullName}}</h1>
computed: {
fullName(){
console.log('执行computed');
return `${this.firstName}·${this.lastName}`
}
},
对比侦听器
从上面两张图可以看出 computed 和 watch 的差异
- 监听值以及变化
watch: 侦听的是属性值, 一旦属性值发生变化,都会触发对应回调来执行响应操作,开销较大
computed: 监听的是依赖值,依赖值不变时直接读取缓存复用,变化时才会重新计算
- 是否异步
watch:可以执行异步操作,例如发送网络请求
computed: 不能执行异步任务,必须同步执行
也就是说,
watch可以监听计算属性
总结:
- 计算属性可以实现的,侦听器也可以,反之不成立
- 能用计算属性尽量使用
问题:计算属性如果是函数,可以传参数吗?
- 可以!通过闭包的方式,计算属性也可以传参数
<h1>{{fullName(1,2)}}</h1>
computed: {
fullName(){
return function(a,b){
console.log(a,b);
return `${this.firstName}·${this.lastName}`
}
}
},
注意: 这样就会失去计算属性的缓存功能