目录

深入理解 Vue 中的 computed 计算属性:原理、用法与实践

一、计算属性的引入:从一个简单案例说起

二、计算属性与普通数据绑定的区别

三、计算属性的特性:缓存机制

四、计算属性的读写操作

五、总结


在 Vue 开发中,computed 计算属性是一项极为实用的特性,无论是在 Vue2 还是 Vue3 项目里,它都发挥着关键作用。本文将通过详细的案例和代码示例,深入剖析 computed 计算属性的方方面面,帮助你更好地掌握这一重要概念。

一、计算属性的引入:从一个简单案例说起

假设我们正在构建一个用户信息输入界面,需要根据用户输入的姓和名,实时计算并展示出全名。在 Vue 中,实现这个功能看似简单,但背后却涉及到一些重要的知识,比如数据绑定和计算属性的运用。

<template>
  <div>
    <input v-model="firstName" placeholder="请输入姓">
    <br>
    <input v-model="lastName" placeholder="请输入名">
    <br>
    <span>全名:{{ fullName }}</span>
    <br>
    <button @click="changeFullName">将全名改为李-四</button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';

// 定义姓和名,使用ref创建响应式数据
const firstName = ref('张');
const lastName = ref('三');

// 使用computed定义计算属性fullName,默认是只读的
const fullName = computed(() => {
  return firstName.value.slice(0, 1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value;
});

// 定义修改全名的方法
const changeFullName = () => {
  // 这里尝试直接修改fullName会报错,因为它是只读的
  // 正确的做法是修改计算属性依赖的数据
  const newFullName = '李-四';
  const [newFirstName, newLastName] = newFullName.split('-');
  firstName.value = newFirstName;
  lastName.value = newLastName;
};
</script>

在上述代码中,我们首先使用ref定义了firstNamelastName两个响应式数据,分别表示姓和名。然后,通过computed定义了fullName计算属性,它依赖于firstNamelastName。每当firstNamelastName发生变化时,fullName都会自动重新计算。

二、计算属性与普通数据绑定的区别

或许你会疑惑,为什么不直接在模板中通过简单的拼接来获取全名,就像这样:

<template>
  <div>
    <input v-model="firstName" placeholder="请输入姓">
    <br>
    <input v-model="lastName" placeholder="请输入名">
    <br>
    <span>全名:{{ firstName + '-' + lastName }}</span>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const firstName = ref('张');
const lastName = ref('三');
</script>

这种方式在简单场景下确实可行,但当逻辑变得复杂时,就会出现问题。例如,如果需要对姓进行首字母大写处理,在模板中直接编写复杂逻辑会使模板变得臃肿且难以维护。Vue 官方文档强调,应尽量让模板保持简单,只包含简单的表达式。此时,计算属性就派上了用场。它将复杂的计算逻辑封装在一个函数中,使模板更加简洁清晰。

三、计算属性的特性:缓存机制

计算属性具有缓存机制,这是它与普通方法的重要区别之一。当计算属性所依赖的数据没有发生变化时,再次访问计算属性不会重新执行计算函数,而是直接返回缓存中的结果。

<template>
  <div>
    <input v-model="firstName" placeholder="请输入姓">
    <br>
    <input v-model="lastName" placeholder="请输入名">
    <br>
    <span>全名:{{ fullName }}</span>
    <br>
    <span>全名(再次展示):{{ fullName }}</span>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';

const firstName = ref('张');
const lastName = ref('三');

const fullName = computed(() => {
  console.log('计算属性被计算');
  return firstName.value + '-' + lastName.value;
});
</script>

在上述代码中,当我们多次在模板中使用fullName时,如果firstNamelastName没有变化,控制台只会打印一次 “计算属性被计算”,这表明计算属性使用了缓存结果。而普通方法每次调用都会执行函数体内的代码,没有缓存机制。

四、计算属性的读写操作

默认情况下,计算属性是只读的。但在某些场景下,我们可能需要对计算属性进行修改,这时就需要使用gettersetter

<template>
  <div>
    <input v-model="firstName" placeholder="请输入姓">
    <br>
    <input v-model="lastName" placeholder="请输入名">
    <br>
    <span>全名:{{ fullName }}</span>
    <br>
    <button @click="changeFullName">将全名改为李-四</button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';

const firstName = ref('张');
const lastName = ref('三');

const fullName = computed({
  get: () => {
    return firstName.value.slice(0, 1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value;
  },
  set: (newValue) => {
    const [newFirstName, newLastName] = newValue.split('-');
    firstName.value = newFirstName;
    lastName.value = newLastName;
  }
});

const changeFullName = () => {
  fullName.value = '李-四';
};
</script>

在这段代码中,我们通过computed传入一个对象,对象中包含getset函数。get函数用于读取计算属性的值,set函数用于设置计算属性的值。当调用changeFullName方法修改fullName时,set函数会被触发,从而实现对计算属性依赖数据的修改,进而更新页面展示。

五、总结

computed 计算属性在 Vue 开发中是一个强大而灵活的工具。它不仅能简化模板中的复杂逻辑,提高代码的可读性和可维护性,还通过缓存机制提升了应用的性能。在实际开发中,合理运用计算属性的读写特性,可以满足各种复杂的业务需求。希望通过本文的介绍,你对 Vue 中的 computed 计算属性有了更深入的理解和掌握,能够在项目开发中熟练运用这一特性,打造出更加高效、优雅的前端应用。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐