Vue3 学习教程,从入门到精通,Vue 3 计算属性(Computed Properties)知识点详解与案例代码(15)
Vue 3 计算属性(Computed Properties)知识点详解与案例代码
在 Vue 3 中,计算属性(Computed Properties) 是用于基于响应式数据派生新数据的一种方式。计算属性具有以下特点:
- 缓存性:只有在依赖的响应式数据发生变化时,计算属性才会重新计算,否则会返回缓存的结果。
- 可读性:计算属性用于获取数据,而不是修改数据。
- 响应性:计算属性会自动追踪其依赖的响应式数据,并在依赖变化时自动更新。
一、计算属性的语法知识点
1. 基本语法
在 Vue 3 中,计算属性通常在 setup
函数中使用 computed
函数来定义。
import { ref, computed } from \'vue\';export default { setup() { const count = ref(0); const doubleCount = computed(() => count.value * 2); return { count, doubleCount }; }};
2. 使用 computed
函数
computed
函数接受一个 getter 函数 作为参数,并返回一个 只读的响应式引用(Readonly Ref)。
const double = computed(() => count.value * 2);
3. 可写的计算属性
默认情况下,计算属性是只读的。如果需要可写的计算属性,可以传递一个包含 get
和 set
方法的对象。
const firstName = ref(\'John\');const lastName = ref(\'Doe\');const fullName = computed({ get: () => `${firstName.value} ${lastName.value}`, set: (value) => { const parts = value.split(\' \'); firstName.value = parts[0]; lastName.value = parts[1]; }});
4. 依赖追踪
计算属性会自动追踪其内部使用的响应式数据,并在这些数据变化时重新计算。
const firstName = ref(\'John\');const lastName = ref(\'Doe\');const fullName = computed(() => `${firstName.value} ${lastName.value}`);
当 firstName
或 lastName
变化时,fullName
会自动更新。
5. 懒计算
计算属性只有在首次访问时才会计算,并且只有在依赖变化时才会重新计算。这使得计算属性在需要复杂计算时非常高效。
二、案例代码
以下是一个完整的 Vue 3 单文件组件(Single File Component, SFC)示例,展示了计算属性的使用,包括基本计算属性、可写的计算属性以及依赖追踪。
Vue 3 计算属性示例
当前计数: {{ count }}
双倍计数: {{ doubleCount }}
名字: {{ firstName }}
姓氏: {{ lastName }}
全名: {{ fullName }}
import { ref, computed } from \'vue\';export default { name: \'ComputedPropertiesExample\', setup() { // 基本计算属性 const count = ref(0); const doubleCount = computed(() => count.value * 2); const increment = () => { count.value++; }; // 可写的计算属性 const firstName = ref(\'John\'); const lastName = ref(\'Doe\'); const fullName = computed({ get: () => `${firstName.value} ${lastName.value}`, set: (value) => { const parts = value.split(\' \'); if (parts.length >= 2) { firstName.value = parts[0]; lastName.value = parts[1]; } else { firstName.value = value; lastName.value = \'\'; } } }); return { count, doubleCount, increment, firstName, lastName, fullName }; }};h1 { color: #42b983;}div { margin-bottom: 20px;}button { padding: 5px 10px; margin-top: 5px;}input { padding: 5px; margin-top: 5px;}
代码详解
-
导入
ref
和computed
import { ref, computed } from \'vue\';
ref
用于创建响应式数据。computed
用于创建计算属性。
-
基本计算属性
const count = ref(0);const doubleCount = computed(() => count.value * 2);
count
是一个响应式的数据。doubleCount
是一个计算属性,其值始终是count
的两倍。
-
增加计数的函数
const increment = () => { count.value++;};
increment
函数用于增加count
的值。
-
可写的计算属性
const fullName = computed({ get: () => `${firstName.value} ${lastName.value}`, set: (value) => { const parts = value.split(\' \'); if (parts.length >= 2) { firstName.value = parts[0]; lastName.value = parts[1]; } else { firstName.value = value; lastName.value = \'\'; } }});
fullName
是一个可写的计算属性。- 当
fullName
被设置时,会自动更新firstName
和lastName
。 - 当
firstName
或lastName
变化时,fullName
也会自动更新。
-
模板部分
<template> <div> <div> <p>当前计数: {{ count }}</p> <p>双倍计数: {{ doubleCount }}</p> <button @click=\"increment\">增加计数</button> </div> <div> <p>全名: {{ fullName }}</p> <input v-model=\"fullName\" placeholder=\"输入全名\" /> <p>名字: {{ firstName }}</p> <p>姓氏: {{ lastName }}</p> </div> <div> <p>名字: {{ firstName }}</p> <p>姓氏: {{ lastName }}</p> <p>全名: {{ fullName }}</p> <input v-model=\"firstName\" placeholder=\"输入名字\" /> <input v-model=\"lastName\" placeholder=\"输入姓氏\" /> </div> </div></template>
- 基本计算属性:展示当前计数和双倍计数,并提供按钮增加计数。
- 可写的计算属性:通过
v-model
绑定fullName
,输入全名会自动更新firstName
和lastName
。 - 依赖追踪示例:展示
firstName
和lastName
,并通过输入框修改它们,fullName
会自动更新。
-
样式部分
h1 { color: #42b983;}div { margin-bottom: 20px;}button { padding: 5px 10px; margin-top: 5px;}input { padding: 5px; margin-top: 5px;}
- 使用
scoped
属性确保样式仅作用于当前组件。 - 设置了一些基本的样式。
- 使用
三、运行效果
-
基本计算属性
- 页面加载时,
count
为0
,doubleCount
为0
。 - 点击“增加计数”按钮,
count
增加,doubleCount
自动更新为count
的两倍。
- 页面加载时,
-
可写的计算属性
- 输入框中输入新的全名,例如
Jane Smith
,firstName
会更新为Jane
,lastName
会更新为Smith
。 - 修改
firstName
或lastName
,fullName
会自动更新。
- 输入框中输入新的全名,例如
-
依赖追踪示例
- 修改
firstName
或lastName
,fullName
会自动更新。 - 修改
fullName
,firstName
和lastName
会根据输入自动调整。
- 修改
四、案例代码
Vue3 计算属性示例
1. 基础只读计算属性
姓:
名:
全名: {{ fullName }}
全名长度: {{ fullNameLength }}
2. 可写计算属性
输入全名:
拆分结果: {{ firstName }} {{ lastName }}
3. 计算属性与方法对比
计算属性 (缓存): {{ reversedMessage }} (访问次数: {{ computedAccessCount }})
方法 (无缓存): {{ reversedMessageMethod() }} (调用次数: {{ methodCallCount }})
当前计数: {{ count }}
import { ref, computed } from \'vue\';// 1. 基础示例数据const firstName = ref(\'张\');const lastName = ref(\'三\');// 基础只读计算属性:计算全名const fullName = computed(() => { // 当firstName或lastName变化时,会重新计算 return `${firstName.value} ${lastName.value}`;});// 计算属性可以依赖其他计算属性const fullNameLength = computed(() => { // 依赖fullName计算属性 return fullName.value.length;});// 2. 可写计算属性示例const fullNameWritable = computed({ // getter:获取值时调用 get() { return `${firstName.value} ${lastName.value}`; }, // setter:设置值时调用 set(newValue) { // 将输入的全名拆分为姓和名 const [first, last] = newValue.split(\' \'); firstName.value = first || \'\'; lastName.value = last || \'\'; }});// 3. 计算属性与方法对比示例const count = ref(0);const message = ref(\'Hello Vue3\');const computedAccessCount = ref(0);const methodCallCount = ref(0);// 计算属性版本:反转消息const reversedMessage = computed(() => { computedAccessCount.value++; return message.value.split(\'\').reverse().join(\'\');});// 方法版本:反转消息function reversedMessageMethod() { methodCallCount.value++; return message.value.split(\'\').reverse().join(\'\');}// 增加计数的方法function incrementCount() { count.value++;}.computed-demo { max-width: 800px; margin: 0 auto; padding: 20px;}div > div { margin-bottom: 30px; padding: 15px; border: 1px solid #e0e0e0; border-radius: 8px;}input { padding: 6px 10px; margin-left: 10px; border: 1px solid #ccc; border-radius: 4px;}button { padding: 8px 16px; background-color: #42b983; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 10px;}button:hover { background-color: #359e75;}
4.1.代码解析
- 基础只读计算属性
fullName
依赖firstName
和lastName
两个响应式数据- 当输入框中的值变化时,
fullName
会自动更新 fullNameLength
依赖fullName
这个计算属性,形成计算属性链
- 可写计算属性
fullNameWritable
同时定义了get
和set
方法- 当读取时,会调用
get
方法拼接全名 - 当修改输入框的值时,会调用
set
方法拆分全名到firstName
和lastName
- 计算属性与方法对比
- 点击按钮只会改变
count
的值,不会影响message
- 计算属性
reversedMessage
因为依赖没有变化,不会重新计算,访问次数不变 - 方法
reversedMessageMethod
每次访问都会重新执行,调用次数会增加
- 点击按钮只会改变
五、总结
通过上述知识点和案例代码,可以看出 Vue 3 的计算属性在处理基于响应式数据的派生数据时非常强大且高效。计算属性不仅简化了代码逻辑,还提高了应用的性能和可维护性。在实际开发中,合理使用计算属性可以大大提升开发效率和代码质量。