Computed 计算属性 总结

好的!计算属性(Computed Properties) 是 Vue 中用于处理复杂逻辑并返回派生数据的核心特性,它的设计目标是简化模板中的复杂表达式自动缓存结果,避免重复计算。以下是详细解释和示例:


核心特点

  1. 依赖追踪
    计算属性会自动追踪其依赖的响应式数据,当依赖发生变化时,计算属性会重新计算;如果依赖未变化,则直接返回缓存值。

  2. 缓存机制
    只有当依赖变化时才会重新计算,避免重复执行复杂逻辑(与普通方法不同,方法在每次渲染时都会执行)。

  3. 声明式语法
    通过 computed 函数定义,逻辑清晰,与模板解耦。


基础用法

示例 1:简单计算
<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

// 计算属性:自动拼接全名
const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});
</script>

<template>
  <input v-model="firstName" placeholder="First Name">
  <input v-model="lastName" placeholder="Last Name">
  <p>Full Name: {{ fullName }}</p>
</template>
  • 说明:当 firstNamelastName 变化时,fullName 自动更新,否则使用缓存值。

示例 2:复杂逻辑(过滤列表)
<script setup>
import { ref, computed } from 'vue';

const searchText = ref('');
const todos = ref([
  { id: 1, text: 'Learn Vue', done: true },
  { id: 2, text: 'Build a project', done: false },
]);

// 计算属性:过滤未完成的任务
const filteredTodos = computed(() => {
  return todos.value.filter(todo => 
    !todo.done && todo.text.includes(searchText.value)
  );
});
</script>

<template>
  <input v-model="searchText" placeholder="Search...">
  <ul>
    <li v-for="todo in filteredTodos" :key="todo.id">
      {{ todo.text }}
    </li>
  </ul>
</template>
  • 说明filteredTodos 依赖 todossearchText,任何变化都会触发重新过滤。

计算属性 vs 方法

方法实现(对比)
<script setup>
// 方法:每次渲染都会执行
function getFullName() {
  return `${firstName.value} ${lastName.value}`;
}
</script>

<template>
  <p>{{ getFullName() }}</p> <!-- 每次渲染都调用 -->
  <p>{{ fullName }}</p>     <!-- 依赖变化时才计算 -->
</template>
  • 关键区别:方法无缓存,计算属性有缓存。

计算属性的 Setter

计算属性默认是只读的,但可以通过 get/set 定义可写属性:

<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`;
  },
  set(newValue) {
    // 当修改 fullName 时,反向拆分赋值
    const [first, last] = newValue.split(' ');
    firstName.value = first;
    lastName.value = last || '';
  }
});

// 测试:修改 fullName
setTimeout(() => {
  fullName.value = 'Jane Smith'; // 触发 set 方法
}, 2000);
</script>
  • 应用场景:需要双向绑定的派生数据(较少使用)。

注意事项

  1. 避免副作用
    计算属性应专注于计算,不要在其中执行异步操作或修改 DOM。

  2. 依赖必须响应式
    如果依赖非响应式数据(如普通变量),计算属性不会更新。

  3. 异步操作不适用
    计算属性不能处理异步逻辑,需改用 watch 或方法。


总结:何时使用计算属性?

  1. 派生数据
    需要基于现有数据生成新数据(如过滤、排序、格式化)。
  2. 复杂逻辑
    模板中不宜写复杂表达式时,用计算属性解耦。
  3. 性能优化
    依赖变化时才重新计算,避免重复执行高开销操作。

问题 1:为什么 fullNameconst 而不是 var

原因

  • const 的作用const 声明的变量不允许重新赋值(即不能指向新值),但不限制其内部值的变更(如果变量是对象或数组)。
  • computed 的特性fullNamecomputed 返回的计算属性引用,其值由内部的 getter 函数动态生成,不需要重新赋值。
  • 防止意外覆盖:用 const 可以避免开发中误操作对 fullName 重新赋值(例如 fullName = newValue),保持代码安全。
const fullName = computed(() => `${firstName.value} ${lastName.value}`);

// ❌ 错误!const 禁止重新赋值
fullName = computed(() => '其他值'); 

// ✅ 允许修改依赖的响应式数据(firstName/lastName)
firstName.value = 'Alice'; 

问题 2:fullName 没有被 ref 包裹,为何视图会更新?

原因

  • computed 的返回值是响应式的computed 内部会创建一个响应式引用(类似 ref 生成的引用对象),自动追踪依赖(firstNamelastName)。
  • 依赖的响应式性firstNamelastNameref 创建的响应式数据,当它们变化时,computed 会重新计算 fullName,并触发视图更新。

验证示例

<script setup>
import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

// fullName 是 computed 生成的响应式引用
const fullName = computed(() => `${firstName.value} ${lastName.value}`);

function changeName() {
  firstName.value = 'Alice'; // 修改依赖项 → 触发 fullName 重新计算
}
</script>

<template>
  <p>{{ fullName }}</p> <!-- 视图会更新! -->
  <button @click="changeName">修改名字</button>
</template>

总结

  1. const 的作用:防止 fullName 被意外重新赋值,与响应式无关。
  2. computed 的响应式性computed 返回的引用本身是响应式的,且自动追踪其依赖的 ref/reactive 数据的变化,无需手动包裹 ref
### Vue3 中 `computed` 计算属性的使用方法 在 Vue 3 中,`computed` 是一种用于定义计算属性的强大工具。它允许开发者以声明式的方式处理响应式数据的复杂逻辑或转换操作[^1]。计算属性的核心特性在于它的 **惰性求值** 和 **缓存机制**,这意味着只有当其依赖的数据发生改变计算属性才会被重新评估。 以下是关于如何在 Vue 3 中使用 `computed` 属性的具体说明以及代码示例: #### 基本语法 计算属性可以通过两种方式实现:选项式 API 或组合式 API (Composition API)。下面分别介绍这两种情况下的写法。 ##### 选项式 API 示例 如果使用的是传统的选项式 API,则可以直接在组件的 `computed` 配置项中定义计算属性[^2]。 ```javascript export default { data() { return { firstName: 'John', lastName: 'Doe' }; }, computed: { fullName() { // 定义一个名为fullName计算属性 return `${this.firstName} ${this.lastName}`; } } }; ``` 在这个例子中,`fullName` 是一个计算属性,它会自动追踪 `firstName` 和 `lastName` 的变化,并返回更新后的全名字符串。 ##### 组合式 API 示例 对于现代项目推荐使用的 Composition API,可以借助 `ref` 来管理状态变量,并通过 `computed` 函数来创建计算属性[^3]。 ```javascript import { ref, computed } from 'vue'; export default { setup() { const firstName = ref('Jane'); const lastName = ref('Smith'); const fullName = computed(() => { return `${firstName.value} ${lastName.value}`; }); return { firstName, lastName, fullName }; } }; ``` 在此案例里,我们利用了 `ref` 创建两个可变的状态变量 (`firstName`, `lastName`) 并将其绑定到视图上;接着用 `computed` 构建了一个只读版本的 `fullName` 属性,该属性会在任何基础字段变动动态调整显示的内容。 #### 在模板中的调用 无论采用哪种形式编写计算属性,在 HTML 模板内的访问都非常简单直观。只需像普通对象成员一样引用即可。 ```html <template> <div> <!-- 调用计算属性 --> Full Name: {{ fullName }} <!-- 修改原始数据 --> First Name: <input v-model="firstName"> Last Name: <input v-model="lastName"> </div> </template> ``` 上述片段展示了如何将输入框与模型关联起来同步修改源数据的同触发相应计算属性的变化效果。 --- ### 总结 综上所述,Vue 3 提供了灵活多样的途径去运用 `computed` 功能简化业务场景下频繁涉及的操作流程。无论是传统还是新型开发模式都能很好地支持这一特性的引入并发挥巨大作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值