面试题:Vue 中 computed 和 methods 的区别是什么?

在 Vue 中,computed(计算属性)和 methods(方法)都可以用来封装逻辑和返回数据,但它们在缓存机制、调用方式和适用场景上有本质区别。

核心区别总结

特性computed (计算属性)methods (方法)
缓存✅ 有缓存。基于响应式依赖进行缓存,依赖不变时,多次访问直接返回缓存结果。❌ 无缓存。每次调用都会重新执行函数体。
调用方式在模板中直接使用(如 {{ fullName }}),不能加 ()在模板中需要加 () 调用(如 {{ getFullName() }})。
依赖追踪✅ 自动追踪其内部使用的响应式数据(dataprops 等)作为依赖。❌ 不追踪依赖,每次调用都执行。
适用场景复杂的数据处理、组合、过滤,且结果依赖于其他响应式数据。事件处理、不依赖响应式数据的逻辑、需要每次都执行的操作。

详细解释

1. 缓存机制 (Cache)

这是最核心的区别。

  • computed 有缓存
    • 计算属性的值是基于它的响应式依赖(比如 data 中的属性)进行缓存的。
    • 只有当它的依赖发生变化时,才会重新计算。
    • 在依赖不变的情况下,无论访问多少次,都会直接返回缓存的结果,不会重新执行函数体。
    • 优点:避免了不必要的重复计算,性能更高。
  • methods 无缓存
    • 每当模板重新渲染或在 JavaScript 中被调用时,方法都会重新执行其函数体。
    • 即使输入参数和内部状态没有变化,也会执行。

示例说明缓存差异

<template>
  <div>
    <!-- computed: 依赖 message 不变时,多次渲染不会重新计算 -->
    <p>Computed: {{ reversedMessage }}</p> 

    <!-- methods: 每次组件更新(如其他数据变化),都会重新调用 -->
    <p>Method: {{ reverseMessage() }}</p> 
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'hello',
      otherData: 'something' // 这个数据变化会触发重新渲染
    }
  },
  computed: {
    reversedMessage() {
      console.log('Computed executed') // 仅在 message 变化时打印
      return this.message.split('').reverse().join('')
    }
  },
  methods: {
    reverseMessage() {
      console.log('Method executed') // 每次渲染都打印(即使 message 没变)
      return this.message.split('').reverse().join('')
    }
  }
}
</script>
  • 如果 otherData 发生变化导致组件重新渲染:
    • reversedMessage 不会重新计算(因为 message 没变),控制台不打印。
    • reverseMessage() 被调用,控制台会打印 “Method executed”。

2. 调用方式

  • computed:在模板中使用时,像一个普通的属性一样访问不能加 ()
    • 正确:{{ fullName }}
    • 错误:{{ fullName() }} (这会尝试调用一个不存在的方法)
  • methods:在模板中作为事件处理器或动态绑定时,需要加 () 来调用
    • 正确:{{ getFullName() }}@click="handleClick"
    • 注意:在 @click 等事件绑定中,() 可以省略(Vue 会自动调用),但作为动态文本绑定时必须加 ()

3. 适用场景

  • 使用 computed 的场景
    • dataprops 中的数据进行复杂计算(如格式化日期、计算总价)。
    • 组合多个数据源(如拼接 firstName 和 lastName 为 fullName)。
    • 过滤或映射数组(如根据搜索条件过滤列表)。
    • 当计算结果依赖于响应式数据,且希望避免重复计算时。
  • 使用 methods 的场景
    • 事件处理函数(如 @click="submitForm")。
    • 执行不依赖响应式数据的逻辑(如生成随机数 Math.random())。
    • 需要每次都执行的操作(如发送日志、触发动画)。
    • 接收参数进行处理(虽然 computed 可以通过返回函数实现,但失去了缓存优势)。

总结

选择 computed 还是 methods 的关键在于:

  • 是否需要缓存? 如果结果依赖于响应式数据,且计算过程较重,优先使用 computed
  • 是否需要每次都执行? 如果是事件处理或需要实时获取最新值(如随机数),则使用 methods
  • 在模板中如何使用? computed 像属性,methods 像函数调用。

合理使用 computed 可以显著提升应用性能,避免不必要的重复计算。

THE END
喜欢就支持一下吧
点赞12 分享