计算属性是基于响应式数据的函数,并且会被缓存,直到相关的响应式数据发生变化。可以在 Vue 组件的 computed
选项中定义计算属性:
1. 定义计算属性
vue2写法
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe'
};
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}
};
vue3写法
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => {
return firstName.value + ' ' + lastName.value;
});
return {
firstName,
lastName,
fullName
};
}
};
2.访问计算属性
<template>
<div>{{ fullName }}</div>
</template>
3.计算属性的使用场景
- 计算和格式化数据
当需要对数据进行计算或格式化时,可以使用计算属性:
import { ref, computed } from 'vue';
export default {
setup() {
const price = ref(100);
const formattedPrice = computed(() => {
return `$${price.value.toFixed(2)}`;
});
return {
price,
formattedPrice
};
}
};
- 基于现有数据生成新数据
计算属性可以用于从现有数据中派生出新的数据:
import { ref, computed } from 'vue';
export default {
setup() {
const tasks = ref([
{ title: 'Task 1', completed: true },
{ title: 'Task 2', completed: false }
]);
const completedTasks = computed(() => {
return tasks.value.filter(task => task.completed);
});
return {
tasks,
completedTasks
};
}
};
- 数据变换
计算属性可以用于将原始数据转换为特定的视图模型:
import { ref, computed } from 'vue';
export default {
setup() {
const message = ref('Hello Vue 3');
const reversedMessage = computed(() => {
return message.value.split('').reverse().join('');
});
return {
message,
reversedMessage
};
}
};
- 依赖多个数据源
计算属性可以依赖多个数据源,当任意一个数据源发生变化时,计算属性会重新计算:
import { ref, computed } from 'vue';
export default {
setup() {
const cartItems = ref([
{ price: 10, quantity: 2 },
{ price: 20, quantity: 1 }
]);
//计算总价
const totalPrice = computed(() => {
return cartItems.value.reduce((sum, item) => sum + item.price * item.quantity, 0);
});
return {
cartItems,
totalPrice
};
}
};
4.计算属性的特性
- 缓存
计算属性的结果会被缓存,直到依赖的数据发生变化:
import { ref, computed } from 'vue';
export default {
setup() {
const someData = ref(1);
const cachedValue = computed(() => {
return someData.value + 1;
});
return {
someData,
cachedValue
};
}
};
- 依赖追踪
计算属性会自动追踪其依赖的数据,当依赖的数据发生变化时,计算属性会重新计算:
import { ref, computed } from 'vue';
export default {
setup() {
const someData = ref(1);
const someComputed = computed(() => {
return someData.value + 1;
});
return {
someData,
someComputed
};
}
};
5.计算属性与方法、监听器的比较
- 计算属性 vs 方法
- 缓存: 计算属性是基于其依赖进行缓存的,只在依赖发生变化时重新计算。方法每次调用都会执行。
- 语法: 计算属性更简洁,特别是在模板中使用时。
import { ref } from 'vue';
export default {
setup() {
const someData = ref(1);
const someMethod = () => {
return someData.value + 1;
};
return {
someData,
someMethod
};
}
};
import { ref, computed } from 'vue';
export default {
setup() {
const someData = ref(1);
const someComputed = computed(() => {
return someData.value + 1;
});
return {
someData,
someComputed
};
}
};
<!-- 使用方法 -->
<template>
<div>{{ someMethod() }}</div>
</template>
<!-- 使用计算属性 -->
<template>
<div>{{ someComputed }}</div>
</template>
- 计算属性 vs 监听器
- 用途: 计算属性主要用于数据的派生和变换,而监听器主要用于在数据变化时执行异步或开销较大的操作。
- 代码结构: 使用计算属性时,逻辑更加清晰和简洁。
import { ref, watch } from 'vue';
export default {
setup() {
const someData = ref(1);
watch(someData, (newValue, oldValue) => {
console.log('someData changed from', oldValue, 'to', newValue);
// 执行异步或开销较大的操作
});
return {
someData
};
}
};
import { ref, computed } from 'vue';
export default {
setup() {
const someData = ref(1);
const someComputed = computed(() => {
return someData.value + 1;
});
return {
someData,
someComputed
};
}
};
6.总结
计算属性在 Vue.js 中是一个非常强大的工具,用于处理基于响应式数据的逻辑。通过缓存和依赖追踪,计算属性能够提高性能并简化代码结构。适当地使用计算属性,可以使代码更加清晰、简洁和高效。
7.使用案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 3 Computed Example in HTML</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<div>
<ul>
<li v-for="product in cart" :key="product.id">
{{ product.name }} - {{ product.price }}
</li>
</ul>
<p>Total Price: {{ totalPrice }}</p>
</div>
</div>
<script>
// 模拟 Vue 3 Composition API 的效果
const cart = [
{ id: 1, name: 'Product A', price: 10 },
{ id: 2, name: 'Product B', price: 15 },
{ id: 3, name: 'Product C', price: 230 }
];
const app = Vue.createApp({
data () {
return {
cart
};
},
// 案例:计算购物车中商品总价
computed: {
totalPrice () {
return this.cart.reduce((total, product) => total + product.price, 0);
}
}
});
app.mount('#app');
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 3 Computed Example in HTML</title>
<script src="https://unpkg.com/vue@3.2.47/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app">
<div>
<input v-model="searchTerm" placeholder="Search">
<ul>
<li v-for="item in filteredList" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</div>
<script>
const { createApp, defineComponent, h, ref } = Vue;
const list = [
{ id: 1, name: 'Item A' },
{ id: 2, name: 'Item B' },
{ id: 3, name: 'Another Item' },
{ id: 3, name: 'Another Item' },
{ id: 3, name: 'Another Item' },
];
const searchTerm = ref('');
const app = Vue.createApp({
data () {
return {
list
};
},
computed: {
filteredList () {
return list.filter(item => item.name.toLowerCase().includes(searchTerm.value.toLowerCase()));
}
}
});
app.mount('#app');
</script>
</body>
</html>