Code前端首页关于Code前端联系我们

Vue3里computed的getter咋用?这些细节你得搞懂!

terry 16小时前 阅读数 107 #SEO
文章标签 Vue3;computed

不少刚上手Vue3的同学,对computed里的getter总是一知半解:它到底有啥用?和methods有啥区别?啥时候该用?今天咱们一个个唠明白。

Vue3 computed里的getter是干啥的?

你可以把getter理解成“自动更新的计算逻辑容器”,比如做购物车时,商品的数量、单价变了,总价得自动跟着变;或者做 Todo 列表时,已完成任务数要实时统计,这些“依赖其他数据、自动更新”的逻辑,就适合塞到computed的getter里。

举个栗子🌰:

<script setup>
import { ref, computed } from 'vue'
const products = ref([
  { price: 10, quantity: 2 },
  { price: 20, quantity: 3 }
])
// 计算总价的getter
const totalPrice = computed({
  get() {
    return products.value.reduce((sum, item) => {
      return sum + item.price * item.quantity
    }, 0)
  }
})
</script>
<template>总价:{{ totalPrice }}</template>

这里products是响应式数据,只要数组里的商品价格/数量变了,totalPrice就会自动重新计算,而且Vue会缓存结果,依赖不变时直接用缓存,不用重复计算,性能更优。

咋写computed的getter?基本语法是啥样?

在Vue3组合式API里,用computed函数创建计算属性,写getter有“简写”和“完整对象”两种方式:

简写形式(只有getter时用):

适合逻辑简单、不需要后续扩展setter的场景,直接传一个函数,这个函数就是getter逻辑:

<script setup>
import { ref, computed } from 'vue'
const count = ref(1)
// 简写:函数就是getter
const doubleCount = computed(() => count.value * 2)
</script>

完整对象形式(适合未来加setter,或想明确区分逻辑):

通过对象的get方法定义逻辑,结构更清晰:

<script setup>
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`
  }
})
</script>
<template>{{ fullName }}</template>

注意⚠️:组合式API里,ref定义的变量要用.value访问,所以getter里操作ref时,别忘写.value,否则拿不到响应式更新!

computed getter和methods里的函数有啥不一样?

最核心的区别是“缓存机制”

  • computed getter有缓存:只要依赖的响应式数据不变,多次访问计算属性会直接读缓存,不会重复执行逻辑。
  • methods里的函数:每次调用都会重新执行函数里的代码,没有缓存。

举个性能对比的例子🌰:如果要对一个大数组做过滤+排序(很耗时):

// 用computed(有缓存,只在bigList变时重新计算)
const filteredList = computed(() => {
  return bigList.value.filter(item => item.flag).sort((a,b) => a.id - b.id)
})
// 用methods(每次调用都重新执行过滤+排序)
function getFilteredList() {
  return bigList.value.filter(item => item.flag).sort((a,b) => a.id - b.id)
}

computed适合“依赖不变时复用结果”的场景(比如计算属性);methods适合“每次调用都要重新执行”的场景(比如点击事件的处理函数)。

getter里能修改数据不?为啥有时要配setter?

默认情况下,computed的getter是只读的,直接给计算属性赋值会报错,但如果需要“通过计算属性赋值,反向修改依赖的原始数据”(比如表单双向绑定),就得给computedsetter

举个双向绑定的栗子🌰:用户输入全名,自动拆分更新firstName和lastName:

<script setup>
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
  get() { // 读取时拼接全名
    return `${firstName.value} ${lastName.value}`
  },
  set(newValue) { // 赋值时拆分更新原始数据
    const [f, l] = newValue.split(' ')
    firstName.value = f
    lastName.value = l
  }
})
</script>
<template><input v-model="fullName" /></template>

这里v-model绑定fullName,用户输入时触发setter,把输入的字符串拆分成firstName和lastName并更新——这就是用setter实现“计算属性双向绑定”的典型场景。

computed getter的响应式依赖咋跟踪的?

Vue的响应式原理可以简单理解为“依赖收集 + 触发更新”

  1. 依赖收集:第一次访问computed的getter时,Vue会偷偷记录“这个getter用到了哪些响应式数据(比如ref/reactive包裹的变量)”,这些被用到的数据,就是getter的“依赖”。
  2. 触发更新:当任何一个依赖发生变化时,Vue会标记这个computed需要重新计算,等下一次访问这个computed时,就会执行getter,算出新结果并缓存。

打个比方🌰:你做了个“今日是否加班”的计算属性,依赖“是否有紧急需求”和“当前时间”,Vue就像个小助手,第一次帮你算“是否加班”时,记下来要盯着这两个数据,之后只要“紧急需求”变了,或者“时间”到了临界点,小助手就会重新帮你算一遍。

写getter时容易踩哪些坑?咋避?

踩过这些坑,你才算真正懂了getter😂:

坑1:忘记解包ref,数据不更新

const count = ref(1)
const wrongDouble = computed(() => count * 2) // 错!count是ref对象,不是数值
const rightDouble = computed(() => count.value * 2) // 对!

避坑:组合式API里,ref变量要用.value访问;reactive对象是代理对象,直接点属性(自动解包)。

坑2:在getter里写异步操作

computed是同步的,getter必须返回同步结果,异步操作(比如await)会导致更新异常:

const wrongAsync = computed(async () => {
  const res = await fetchData()
  return res.data
}) // 错!返回的是Promise,computed没法处理

避坑:异步逻辑改用watchwatchEffect,或者在onMounted里请求数据,把结果存在ref里,再用computed处理这个ref

坑3:依赖非响应式数据,getter不更新

let normalCount = 1 // 普通变量,非响应式
const wrongComputed = computed(() => normalCount * 2)
function increment() {
  normalCount++ // Vue感知不到变化,getter不会更新
}

避坑:getter里用到的所有数据,都要用refreactive包成响应式的,Vue才能跟踪变化。

实际项目里,哪些场景必须用computed getter?

这些场景用computed,代码更简洁、性能更优:

  • 需要缓存的复杂计算:比如表格筛选/排序、购物车总价计算,用computed避免重复执行耗时逻辑。
  • 模板中多次复用的计算结果:比如页面多个地方显示用户全名(firstName + lastName),用computed只算一次,到处复用。
  • 多响应式数据的派生状态:比如购物车“是否全选”(依赖每个商品的选中状态)、表单“是否可提交”(依赖多个输入框的验证状态)。
  • 需要双向绑定的表单:像前面的全名输入框,用computed配合setter实现优雅的双向绑定。

最后总结下:computed的getter是Vue帮我们处理“依赖跟踪、自动更新、结果缓存”的利器,理解它的语法、缓存机制、响应式原理,避开常见的坑,才能在项目里用得顺手,下次写代码时,别再把computed和methods搞混啦~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门