computed 是一种用于声明计算属性的 API。计算属性是一种根据其他数据的变化而动态计算得到的属性,它们的值会被缓存,只有在相关依赖发生变化时才会重新计算。
import { ref, computed } from 'vue';
const data = ref(5);
// 创建一个计算属性
const squared = computed(() => {
return data.value * data.value;
});
console.log(squared.value); // 输出 25
// 当 data 的值变化时,squared 会自动更新
data.value = 6;
console.log(squared.value); // 输出 36
在上面的例子中,squared 是一个计算属性,它依赖于 data 的值。计算属性的定义是一个函数,该函数返回计算的结果。在模板或其他计算属性中,你可以通过访问 squared.value 来获取计算属性的值。
计算属性的依赖:
Vue 3 会追踪计算属性的依赖关系,当依赖的数据发生变化时,计算属性会被重新计算。在上面的例子中,squared 依赖于 data,所以当 data 变化时,squared 会重新计算。
计算属性的 Setter:
你还可以为计算属性提供一个 setter 函数,用于处理对计算属性的赋值操作。
import { ref, computed } from 'vue';
const data = ref(5);
// 创建一个计算属性
const squared = computed({
get: () => data.value * data.value,
set: (value) => {
// 在这里处理对计算属性的赋值操作
data.value = Math.sqrt(value);
}
});
console.log(squared.value); // 输出 25
// 赋值操作会调用 setter
squared.value = 36;
console.log(data.value); // 输出 6
在上面的例子中,当对 squared 进行赋值操作时,会调用 set 函数,然后更新 data 的值。这种方式允许你在计算属性被修改时执行一些额外的逻辑。
总体来说,computed 计算属性是 Vue 中一种非常强大且方便的特性,使你能够以声明式的方式定义派生状态。
<template>
<div class="person">
姓:<input type="text" v-model="firstName" /><br />
名:<input type="text" v-model="lastName" /><br />
全名:<span>{{ fullName }}</span> <br />
<!-- {{ fullName2() }}
{{ fullName2() }}
{{ fullName2() }}
{{ fullName2() }}
{{ fullName2() }} -->
</div>
</template>
<script lang="ts" setup name="Person">
import { ref, computed } from "vue";
let firstName = ref("张");
let lastName = ref("三");
// 方法会调用多次
function fullName2(){
console.log('fullName2')
return firstName.value + "-" + lastName.value;
}
// 计算属性有缓存,只会调用一次
// 这么定义的fullName是一个计算属性,且是只读的
/* let fullName = computed(() => {
console.log('computed-----fullName')
return firstName.value + "-" + lastName.value;
}); */
let fullName =computed({
get(){
return firstName.value + "-" + lastName.value;
},
set(val){
const [str1,str2] = val.split('-')
firstName.value=str1;
lastName.value=str2;
}
})
</script>
<style>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
.button {
margin: 0 5px;
}
.li {
font-size: 30px;
}
</style>
网友评论