# 1. 提问:computed 什么情况下使用?

App 为根组件 下面 Home 例子都被此组件引用

vue
// App.vue 
<template>
  <div>
    <home></home>
  </div>
</template>
<script>
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
};
</script>
<style scoped>
</style>
vue
// Home.vue
<template>
  <div>
    <!-- -->
    <h2>firstName:{{ firstName }}</h2>
    <h2>lastName:{{ lastName }}</h2>
    <h2>fullName:{{ fullName }}</h2>
    <button @click="changeName">修改fullName</button>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const firstName = ref("Nico");
    const lastName = ref("Niconi");
    const fullName = firstName.value + " " + lastName.value;
    const changeName = () => {
      // 可以得出 fullName 不是响应式的
      lastName.value = "aimer"; // 改变 lastName 为 aimer 打印结果也并没有发生改变
      console.log("fullName:", fullName);
    };
    return {
      fullName,
      lastName,
      firstName,
      changeName,
    };
  },
};
</script>
<style scoped>
</style>

参考结果:

setup_computed

# 2. 使用 computed 传入一个 getter 函数

vue
// Home.vue
<template>
  <div>
    <!-- -->
    <h2>firstName:{{ firstName }}</h2>
    <h2>lastName:{{ lastName }}</h2>
    <h2>fullName:{{ fullName }}</h2>
    <button @click="changeName">修改fullName</button>
  </div>
</template>
<script>
import { ref, computed } from "vue";
export default {
  setup() {
    const firstName = ref("Nico");
    const lastName = ref("Niconi");
    const fullName = computed(() => firstName.value + " " + lastName.value);
    const changeName = () => {
      // 使用 computed 里面可以写成一个函数,再 return 出结果 则是响应式的!
      lastName.value = "aimer"; // 改变 lastName 为 aimer 打印结果也已经发生了改变
      console.log("fullName:", fullName);
    };
    return {
      fullName,
      lastName,
      firstName,
      changeName,
    };
  },
};
</script>
<style scoped>
</style>

参考结果:

setup_computed

# 3. 传入一个对象,对象包含 (getter/setter)

vue
// Home.vue
<template>
  <div>
    <!-- -->
    <h2>firstName:{{ firstName }}</h2>
    <h2>lastName:{{ lastName }}</h2>
    <h2>fullName:{{ fullName }}</h2>
    <button @click="changeName">修改fullName</button>
  </div>
</template>
<script>
import { ref, computed } from "vue";
export default {
  setup() {
    const firstName = ref("Nico");
    const lastName = ref("Niconi");
    console.log("原数据:", firstName.value + " " + lastName.value);
    const fullName = computed({
      get: () => firstName.value + " " + lastName.value,
      set: (newValue) => {
        // 通过下面打印,也能拿到 下面修改的值 newValue = Nekoaimer
        console.log("newValue:", newValue);
        // 因此可以进行一些操作 下面举个栗子:
        firstName.value = newValue.split(" ")[0];
        lastName.value = newValue.split(" ")[1];
      },
    });
    const changeName = () => {
      // 返回的 fullName 依然是一个 ref 对象, 所以修改 fullName 依然是使用 value
      fullName.value = "Neko aimer"; // 改变 fullName 值为 Nekoaimer
      console.log("fullName:", fullName);
    };
    return {
      fullName,
      lastName,
      firstName,
      changeName,
    };
  },
};
</script>
<style scoped>
</style>

参考结果:

setup_computed

# 4. 总结

  • 变量去接收一些经过一些列逻辑处理或者操作时,返回的结果并不是响应式数据
  • 而 computed 就是在这种场景,用来解决这个问题的
  • computed 一般只使用 get,所以默认返回一个函数
  • 但特殊情况下也可以传入对象,使用 get 与 set 进行一些逻辑操作