Skip to content

计算属性

只读计算属性

计算属性 被用来描述依赖响应式状态的复杂逻辑。

vue
<template>
	<div>{{ fullName }}</div>
</template>

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

  const firstName = ref("tom");
  const lastName = ref("jerry");

  const fullName = computed(() => {
    return `${firstName.value} & ${lastName.value}`;
  });

  setTimeout(() => {
    // [Vue warn] Write operation failed: computed value is readonly
    computedValue.value = "张 & 李"; // 不要直接修改计算属性的值
  }, 5000);
</script>

可写计算属性

计算属性默认是 只读 的,当修改计算属性时,控制台会报警告。

在某些场景下,如果真的想要修改计算属性的值,则需要通过 getter 和 setter 函数来解决。

vue
<template>
	<div>{{ fullName }}</div>
</template>

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

  const firstName = ref("tom");
  const lastName = ref("jerry");

  const fullName = computed({
    // getter
    get() {
      return `${firstName.value} & ${lastName.value}`;
    },
    // setter
    set(newValue) {
      [firstName.value, lastName.value] = newValue.split("&");
    }
  });

  setTimeout(() => {
    fullName.value = "刘 & 亦"; // 改变计算属性的值
  }, 5000);
</script>

获取上一个值3.4+

如果需要,可以通过访问计算属性的 getter 的第一个参数来获取计算属性返回的上一个值。

vue
<template>
	<div>{{ valueComp }}</div>
</template>

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

  const count = ref(1);

  const valueComp = computed((previous) => {
    if (count.value < 5) {
      return count.value;
    }
    return previous;
  });

  setInterval(() => {
    count.value++;
  }, 1000);
</script>
vue
<template>
	<div>{{ valueComp }}</div>
</template>

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

  const count = ref(1);

  const valueComp = computed({
    get(previous) {
      if (count.value < 5) {
        return count.value;
      }
      return previous;
    },
    set(newValue) {
      // ...
    }
  });

  setInterval(() => {
    count.value++;
  }, 1000);
</script>

Computed传参数不推荐

在某些情况下,需要给 Computed 传递参数的时候,可以给 Computed 返回一个闭包函数。(不推荐使用,只做一下记录!!)

vue
<template>
	<div v-for="item in 10">
  	{{ render(item) }}
  </div>
</template>

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

  // 通过computed创建一个闭包函数,每次 render(item) 被调用时,都会执行这个闭包函数
  // 缺点:无法缓存结果,性能也不好,不如直接使用 methods
  const render = computed(() => {
    return (value) => {
      return value % 2 === 0 ? `${value}是偶数` : `${value}是奇数`;
    };
  });
</script>

Released under the MIT License.