元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
Vue3 基础
▶
环境搭建
安装与配置
项目创建
开发工具
▶
模板语法
插值表达式
指令系统
事件处理
▶
核心概念
▶
响应式系统
ref与reactive
计算属性
侦听器
▶
组合式API
setup函数
生命周期钩子
自定义Hooks
▶
组件开发
▶
组件基础
组件通信
Props详解
插槽机制
▶
高级组件
动态组件
异步组件
递归组件
▶
状态管理
▶
Vuex基础
状态存储
模块化
组合式写法
▶
Pinia
创建Store
状态操作
插件机制
发布时间:
2025-03-22 12:11
↑
☰
# Vue3 计算属性详解 本文将详细介绍Vue3中计算属性的概念、使用方法和最佳实践,帮助你更好地理解和使用这一重要特性。 ## 计算属性基础 ### 1. 基本用法 ```vue <template> <div> <p>原始消息: {{ message }}</p> <p>反转消息: {{ reversedMessage }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const message = ref('Hello Vue3') // 定义计算属性 const reversedMessage = computed(() => { return message.value.split('').reverse().join('') }) </script> ``` ### 2. 计算属性vs方法 ```vue <template> <div> <!-- 计算属性 --> <p>{{ reversedMessage }}</p> <!-- 方法 --> <p>{{ reverseMessage() }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const message = ref('Hello Vue3') // 计算属性:结果会被缓存 const reversedMessage = computed(() => { console.log('计算属性被执行') return message.value.split('').reverse().join('') }) // 方法:每次访问都会执行 const reverseMessage = () => { console.log('方法被执行') return message.value.split('').reverse().join('') } </script> ``` ## 计算属性的特性 ### 1. 缓存机制 ```vue <template> <div> <p>{{ expensiveComputation }}</p> <p>{{ expensiveComputation }}</p> <p>{{ expensiveComputation }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const count = ref(0) // 耗时计算只会执行一次 const expensiveComputation = computed(() => { console.log('执行计算') return Array(1000000).fill(0).reduce((a, b) => a + b) + count.value }) </script> ``` ### 2. 依赖追踪 ```vue <template> <div> <p>Full Name: {{ fullName }}</p> <button @click="updateFirstName">Update First Name</button> <button @click="updateLastName">Update Last Name</button> </div> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('John') const lastName = ref('Doe') // 自动追踪firstName和lastName的变化 const fullName = computed(() => { console.log('fullName重新计算') return `${firstName.value} ${lastName.value}` }) const updateFirstName = () => { firstName.value = 'Jane' } const updateLastName = () => { lastName.value = 'Smith' } </script> ``` ## 可写计算属性 ### 1. 基本用法 ```vue <template> <div> <input v-model="fullName" /> <p>First Name: {{ firstName }}</p> <p>Last Name: {{ lastName }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('John') const lastName = ref('Doe') const fullName = computed({ // getter get() { return `${firstName.value} ${lastName.value}` }, // setter set(newValue) { [firstName.value, lastName.value] = newValue.split(' ') } }) </script> ``` ### 2. 数据验证 ```vue <template> <div> <input v-model="price" type="number" /> <p>Formatted Price: {{ formattedPrice }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const price = ref(0) const formattedPrice = computed({ get() { return `$${price.value.toFixed(2)}` }, set(newValue) { // 移除非数字字符并转换为数字 const value = Number(newValue.replace(/[^0-9.-]/g, '')) // 验证是否为有效数字 price.value = isNaN(value) ? 0 : value } }) </script> ``` ## 最佳实践 ### 1. 合理使用计算属性 ```vue <template> <div> <!-- 不推荐:在模板中进行复杂计算 --> <p>{{ items.filter(item => item.completed).length }}</p> <!-- 推荐:使用计算属性 --> <p>{{ completedItemCount }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const items = ref([ { id: 1, text: 'Task 1', completed: true }, { id: 2, text: 'Task 2', completed: false }, { id: 3, text: 'Task 3', completed: true } ]) const completedItemCount = computed(() => { return items.value.filter(item => item.completed).length }) </script> ``` ### 2. 链式计算属性 ```vue <template> <div> <p>Active Users: {{ activeUserCount }}</p> <p>Active Premium Users: {{ activePremiumUserCount }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const users = ref([ { id: 1, name: 'John', active: true, premium: true }, { id: 2, name: 'Jane', active: true, premium: false }, { id: 3, name: 'Bob', active: false, premium: true } ]) // 先筛选活跃用户 const activeUsers = computed(() => { return users.value.filter(user => user.active) }) // 基于activeUsers再筛选高级用户 const activePremiumUsers = computed(() => { return activeUsers.value.filter(user => user.premium) }) // 计数 const activeUserCount = computed(() => activeUsers.value.length) const activePremiumUserCount = computed(() => activePremiumUsers.value.length) </script> ``` ### 3. 性能优化 ```vue <template> <div> <input v-model="searchQuery" /> <ul> <li v-for="item in filteredItems" :key="item.id"> {{ item.name }} </li> </ul> </div> </template> <script setup> import { ref, computed } from 'vue' const items = ref([ { id: 1, name: 'Item 1', category: 'A' }, { id: 2, name: 'Item 2', category: 'B' }, { id: 3, name: 'Item 3', category: 'A' } ]) const searchQuery = ref('') const selectedCategory = ref('all') // 分步骤进行计算,提高性能 const itemsByCategory = computed(() => { if (selectedCategory.value === 'all') return items.value return items.value.filter(item => item.category === selectedCategory.value) }) const filteredItems = computed(() => { const query = searchQuery.value.toLowerCase() if (!query) return itemsByCategory.value return itemsByCategory.value.filter(item => item.name.toLowerCase().includes(query) ) }) </script> ``` ## 注意事项 ### 1. 避免直接修改计算属性 ```vue <script setup> import { ref, computed } from 'vue' const count = ref(0) // 只读计算属性 const doubleCount = computed(() => count.value * 2) // 错误:不能直接修改计算属性 // doubleCount.value = 10 // 这会报错 // 正确:修改源数据 const updateCount = () => { count.value += 1 } </script> ``` ### 2. 避免副作用 ```vue <script setup> import { ref, computed } from 'vue' const count = ref(0) // 不推荐:在计算属性中产生副作用 const badComputed = computed(() => { console.log('Side effect') // 避免这样做 return count.value * 2 }) // 推荐:使用侦听器处理副作用 import { watch } from 'vue' watch(() => count.value, (newValue) => { console.log('Count changed:', newValue) }) </script> ``` ## 总结 本文详细介绍了Vue3中计算属性的使用: 1. 基础概念 - 基本用法 - 计算属性vs方法 - 缓存机制 2. 高级特性 - 可写计算属性 - 依赖追踪 - 链式计算 3. 最佳实践 - 合理使用场景 - 性能优化 - 注意事项 通过合理使用计算属性,可以让代码更加简洁、高效,并提高应用的性能。建议在开发中根据具体场景选择合适的使用方式,并注意避免常见的陷阱。