计算属性是基于响应式数据的函数,并且会被缓存,直到相关的响应式数据发生变化。可以在 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.计算属性与方法、监听器的比较
- 缓存: 计算属性是基于其依赖进行缓存的,只在依赖发生变化时重新计算。方法每次调用都会执行。
- 语法: 计算属性更简洁,特别是在模板中使用时。
| 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> |
复制
- 用途: 计算属性主要用于数据的派生和变换,而监听器主要用于在数据变化时执行异步或开销较大的操作。
- 代码结构: 使用计算属性时,逻辑更加清晰和简洁。
| 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> |
| |
| 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> |
复制