> 技术文档 > Vue3 学习教程,从入门到精通,Vue 3 计算属性(Computed Properties)知识点详解与案例代码(15)

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. 可写的计算属性

默认情况下,计算属性是只读的。如果需要可写的计算属性,可以传递一个包含 getset 方法的对象。

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}`);

firstNamelastName 变化时,fullName 会自动更新。

5. 懒计算

计算属性只有在首次访问时才会计算,并且只有在依赖变化时才会重新计算。这使得计算属性在需要复杂计算时非常高效。


二、案例代码

以下是一个完整的 Vue 3 单文件组件(Single File Component, SFC)示例,展示了计算属性的使用,包括基本计算属性、可写的计算属性以及依赖追踪。

 

Vue 3 计算属性示例

当前计数: {{ count }}

双倍计数: {{ doubleCount }}

全名: {{ fullName }}

名字: {{ firstName }}

姓氏: {{ lastName }}

名字: {{ 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;}

代码详解

  1. 导入 refcomputed

    import { ref, computed } from \'vue\';
    • ref 用于创建响应式数据。
    • computed 用于创建计算属性。
  2. 基本计算属性

    const count = ref(0);const doubleCount = computed(() => count.value * 2);
    • count 是一个响应式的数据。
    • doubleCount 是一个计算属性,其值始终是 count 的两倍。
  3. 增加计数的函数

    const increment = () => { count.value++;};
    • increment 函数用于增加 count 的值。
  4. 可写的计算属性

    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 被设置时,会自动更新 firstNamelastName
    • firstNamelastName 变化时,fullName 也会自动更新。
  5. 模板部分

    <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,输入全名会自动更新 firstNamelastName
    • 依赖追踪示例:展示 firstNamelastName,并通过输入框修改它们,fullName 会自动更新。
  6. 样式部分

    h1 { color: #42b983;}div { margin-bottom: 20px;}button { padding: 5px 10px; margin-top: 5px;}input { padding: 5px; margin-top: 5px;}
    • 使用 scoped 属性确保样式仅作用于当前组件。
    • 设置了一些基本的样式。

三、运行效果

  1. 基本计算属性

    • 页面加载时,count0doubleCount0
    • 点击“增加计数”按钮,count 增加,doubleCount 自动更新为 count 的两倍。
  2. 可写的计算属性

    • 输入框中输入新的全名,例如 Jane SmithfirstName 会更新为 JanelastName 会更新为 Smith
    • 修改 firstNamelastNamefullName 会自动更新。
  3. 依赖追踪示例

    • 修改 firstNamelastNamefullName 会自动更新。
    • 修改 fullNamefirstNamelastName 会根据输入自动调整。

四、案例代码

 

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.代码解析

  1. 基础只读计算属性
    • fullName 依赖 firstNamelastName 两个响应式数据
    • 当输入框中的值变化时,fullName 会自动更新
    • fullNameLength 依赖 fullName 这个计算属性,形成计算属性链
  2. 可写计算属性
    • fullNameWritable 同时定义了 getset 方法
    • 当读取时,会调用 get 方法拼接全名
    • 当修改输入框的值时,会调用 set 方法拆分全名到 firstNamelastName
  3. 计算属性与方法对比
    • 点击按钮只会改变 count 的值,不会影响 message
    • 计算属性 reversedMessage 因为依赖没有变化,不会重新计算,访问次数不变
    • 方法 reversedMessageMethod 每次访问都会重新执行,调用次数会增加

五、总结

通过上述知识点和案例代码,可以看出 Vue 3 的计算属性在处理基于响应式数据的派生数据时非常强大且高效。计算属性不仅简化了代码逻辑,还提高了应用的性能和可维护性。在实际开发中,合理使用计算属性可以大大提升开发效率和代码质量。