目录

21computed-和-watch-区分使场景

21、computed 和 watch 区分使⽤场景

computed: 适用于根据已有数据进行计算得出新数据的场景,尤其是当计算逻辑比较复杂,且依赖的数据会多次被使用时。计算属性会根据依赖自动缓存结果,只有依赖发生变化时才会重新计算。

示例

<template>
  <div>
    <!-- 显示计算属性的值 -->
    <p>Reversed message: {{ reversedMessage }}</p>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  computed: {
    reversedMessage() {
      // 计算属性,返回反转后的消息
      return this.message.split('').reverse().join('');
    }
  },
  methods: {
    changeMessage() {
      // 修改消息内容
      this.message = 'New message';
    }
  }
};
</script>

在上述示例中:

  1. reversedMessage 是一个计算属性,它依赖于 message 数据。
  2. 当首次访问 reversedMessage 时,Vue 会执行 reversedMessage 的 getter 函数,将 message 反转并返回结果,同时将结果缓存起来。
  3. 后续多次访问 reversedMessage 时,如果 message 没有发生变化,Vue 会直接返回缓存的结果,而不会重新执行 splitreversejoin 操作。
  4. 当点击按钮调用 changeMessage 方法修改 message 的值时, message 发生变化, reversedMessage 的缓存被标记为无效。下一次访问 reversedMessage 时,Vue 会重新执行 getter 函数,计算新的反转结果并更新缓存。

1. 语法和定义方式

  • computed :是一个对象,其中的每个属性都是一个计算属性,通过定义一个 getter 函数来计算属性的值。也可以提供 setter 函数来实现双向绑定。

vue

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

<script>
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
};
</script>
  • watch :也是一个对象,键是要监听的数据属性名,值可以是一个函数、一个字符串(方法名)或者一个包含 handler 函数和其他配置选项的对象。

vue

<template>
  <div>
    <input v-model="message" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  },
  watch: {
    message(newValue, oldValue) {
      console.log(`Message changed from ${oldValue} to ${newValue}`);
    }
  }
};
</script>

2. 使用场景

  • computed :适用于根据已有数据进行计算得出新数据的场景,尤其是当计算逻辑比较复杂,且依赖的数据会多次被使用时。计算属性会根据依赖自动缓存结果,只有依赖发生变化时才会重新计算。
    • 例如,根据用户输入的单价和数量计算总价,或者对数组进行排序、过滤等操作。
  • watch :主要用于监听数据的变化,并在数据变化时执行特定的操作,如异步请求、调用第三方 API、触发动画等。
    • 例如,当用户输入的搜索关键词发生变化时,发起搜索请求;或者当某个数据发生变化时,更新页面上的其他元素。

3. 性能

  • computed :由于具有缓存机制,只要依赖的数据没有变化,多次访问计算属性都会直接返回缓存的结果,避免了重复计算,性能较高。
  • watch :每次监听的数据发生变化时,都会执行相应的回调函数,即使数据变化后执行的操作与之前相同,也会重新执行,可能会导致性能开销。

4. 响应式机制

  • computed :是基于响应式依赖进行计算的,它会自动追踪其依赖的数据。当依赖的数据发生变化时,计算属性会自动更新。
  • watch :需要手动指定要监听的数据属性,当监听的数据发生变化时,会触发相应的回调函数。

5. 双向绑定支持

  • computed :可以通过提供 setter 函数来实现双向绑定。

vue

<template>
  <input v-model="fullName" />
</template>

<script>
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    fullName: {
      get() {
        return `${this.firstName} ${this.lastName}`;
      },
      set(newValue) {
        const names = newValue.split(' ');
        this.firstName = names[0];
        this.lastName = names[1];
      }
    }
  }
};
</script>
  • watch :通常用于单向的数据监听和处理,不直接支持双向绑定。但可以在 watch 的回调函数中手动更新其他数据来实现类似双向绑定的效果。