Vue2的计算属性
在Vue2文档上存在这么一个例子:通过计算属性来获取全名
javascript
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
同时,如果我们更改了计算属性时,响应式数据也需要同步更改,所以文档上还给出了另外一个完善的例子:计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
javascript
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
在Vue3中按照Vue2的模式使用计算属性
之前在**setup 博文**中说过,如果Vue2 和 Vue3的语法混用了,在Vue2 中的配置 (例如:data、methods、compute、watch等)可以访问到 setup 中的属性和方法。所以我们试试在 Vue3 中使用 Vue2 的语法来实现计算属性
javascript
<template>
<p>姓:<input type="text" v-model="user.firstName"> </p>
<p>名:<input type="text" v-model="user.lastName"> </p>
<p>全称 {{ fullName }}</p>
</template>
<script>
import { ref } from "vue";
export default {
name: "TestComponent",
computed: {
fullName() {
// vue2 中,必须使用this才能取得数据
return this.user.firstName + '-' + this.user.lastName;
}
},
setup() {
let user = ref({ firstName: "张", lastName: "三" });
return {
user,
};
},
};
</script>
到这里我们发现,确实是可以通过Vue2的方式在Vue3的 setup 中取得数据且完成效果。
Vue3 中的计算属性
上面说的是Vue2 和 Vue3 混用,现在我们来看看真正的Vue3的计算属性时怎么使用的。
首先,因为 Vue3 是组合式的,所以我们在使用 computed 计算属性时,需要像 ref\reactive 一样,引入之后再使用。且Vue3 中的 computed 计算属性是一个函数,接收的参数可以是一个函数(简写形式-只读) 或 对象形式(读和写)。
javascript
<template>
<!-- 通过 ref 转化的响应式属性,在模板中使用setup 中的变量时,会自动解包,而不用使用 value -->
<p>姓:<input type="text" v-model="user.firstName"> </p>
<p>名:<input type="text" v-model="user.lastName"> </p>
<p>全称: {{ fullName }}</p>
</template>
<script>
// 通过 import 引入组合式的 api
import { ref,computed } from "vue";
export default {
name: "TestComponent",
setup() {
// 这里是使用 ref 来将对象转化为响应式,所以在 setup 中使用时,需要通过.value
let user = ref({ firstName: "张", lastName: "三" });
// 计算属性-- computed 现在是一个函数,因为只有读取时的操作,所以接收一个函数参数,反正是在 setup 中没有 this,直接使用箭头函数更加方便
// 且因为是 ref 转化的响应式,所以需要 .value 解包
let fullName = computed(() => {
return user.value.firstName + '-' + user.value.lastName;
})
return {
user,
fullName
};
},
};
</script>
但是这么写其实存在一个优化点,因为 Vue3 现在对于对象的响应式时通过Proxy代理实现的,是针对于对象的,现在可以直接删除或添加属性的同时还能实现响应式,而不用像Vue2一样还需要依赖 set、delete 等api。
所以我们可以直接向 user 对象中添加一个 fullName 属性来接收计算属性返回的值,从而少声明一个变量。
javascript
<template>
<!-- 通过 ref 转化的响应式属性,在模板中使用setup 中的变量时,会自动解包,而不用使用 value -->
<p>姓:<input type="text" v-model="user.firstName"> </p>
<p>名:<input type="text" v-model="user.lastName"> </p>
<p>全称: {{ user.fullName }}</p>
</template>
<script>
import { ref,computed } from "vue";
export default {
name: "TestComponent",
setup() {
let user = ref({ firstName: "张", lastName: "三" });
// 计算属性--不会自动解包,所以需要使用 .value
user.value.fullName = computed(() => {
return user.value.firstName + '-' + user.value.lastName;
})
return {
user, // 直接返回 user ,user中包含三个属性:firstName、lastName、fullName
};
},
};
</script>
在Vue2 的例子中,我们改变了计算属性,同时响应式数据夜同步发生改变,我们现在在Vue3的语法中同样可以实现,且方法大致上和 Vue2 一致。
html
<template>
<!-- 通过 ref 转化的响应式属性,在模板中使用setup 中的变量时,会自动解包,而不用使用 value -->
<p>姓:<input type="text" v-model="user.firstName"> </p>
<p>名:<input type="text" v-model="user.lastName"> </p>
<p>全称: <input type="text" v-model="user.fullName"> </p>
</template>
<script>
import { ref,computed } from "vue";
export default {
name: "TestComponent",
setup() {
let user = ref({ firstName: "张", lastName: "三" });
// 计算属性--因为同时存在读取和写入两个操作,所以接收的参数是一个对象,包含 get 和 set 两个方法
user.value.fullName = computed({
get(){
return user.value.firstName + '-' + user.value.lastName;
},
set(value) {
let val = value.split('-');
user.value.firstName = val[0]
user.value.lastName = val[1]
}
})
return {
user,
};
},
};
</script>
从gif可以看出,计算属性和响应式数据的更改都是可以互相同步影响的。
总结
在Vue2 或 Vue3 中的计算属性的功能都是一致的:允许开发者定义基于响应式数据的动态值。这些值会自动缓存,并且仅在依赖的数据发生变化时重新计算。这为开发者提供了一种更高效和简洁的方式来处理复杂的数据操作和逻辑。
区别在于使用方式,因为Vue2采用的是配置式( 直接通过属性调用,计算属性是一个对象 ),Vue3采用的是组合式(需要引入才能使用,计算属性是一个函数,参数可以是一个函数--只读状态,也可以是一个对象--读取+写入状态均存在)。