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

Vue3里的computed该咋用?常见疑问一次讲透

terry 2小时前 阅读数 20 #SEO
文章标签 Vue3 computed

Vue3的computed是做什么的?

咱得先明白,computed叫“计算属性”,核心作用是基于其他响应式数据,生成新的响应式结果,举个日常例子:你做个人信息页面时,有firstName(姓)和lastName(名)两个响应式变量,想拼接出“全名”展示——这时候用computed就特合适,代码大概长这样:

import { ref, computed } from 'vue'
const firstName = ref('张')
const lastName = ref('三')
const fullName = computed(() => `${firstName.value}${lastName.value}`)

此时fullName就是计算属性,它会自动“盯紧”firstNamelastName:只要这俩变量有一个变化,fullName就会自动更新,而且在模板里用{{ fullName }}时,不用像methods那样加括号调用,因为computed返回的是“自动更新的结果”,不是函数~

computed和methods有啥不一样?

最关键的区别在缓存机制调用逻辑上:

  • methods:每次模板渲染或手动调用时,函数都会重新执行一遍,比如做“时间格式化”功能,页面里多处显示“xx分钟前”——用methods的话,每次页面刷新(哪怕时间源没变化),都会重新计算时间差。
  • computed:有缓存,只有依赖的响应式数据变化时,才会重新计算,还是拿“购物车商品总价”举例:商品列表里每个商品的价格、数量是响应式的,用computed计算总价时,只有某件商品的价格/数量变了,才会重新计算;要是用methods,每次页面刷新(哪怕数据没变化)都得重新遍历列表计算,性能差很多。

所以总结个小原则:需要依赖其他数据、且频繁访问的“计算逻辑”,优先用computed;事件处理(比如点击按钮)、一次性逻辑(比如初始化数据)这类场景,用methods更合适~

复杂逻辑下,computed咋写?

默认情况下,computed只读的(只有getter),但如果需要“双向绑定”或主动修改计算属性,就得用getset结合的写法,比如用户资料里的“全名”,既要能显示(get),又要能通过输入全名拆分姓和名(set),看代码示例:

const firstName = ref('')
const lastName = ref('')
const fullName = computed({
  get() {
    return `${firstName.value}·${lastName.value}`
  },
  set(newValue) {
    // 假设输入格式是“姓·名”,拆分后赋值
    const [first, last] = newValue.split('·')
    firstName.value = first
    lastName.value = last
  }
})

这时在模板里给fullNamev-model绑定输入框,用户输入新全名时,set函数会触发,自动更新firstNamelastName,这种“读写分离”的场景,computedget/set组合就特别好用~

computed的缓存机制咋理解?啥时候重新计算?

缓存机制的核心是“依赖追踪”computed会自动跟踪它用到的响应式数据(也就是“依赖项”),只有这些依赖项变化时,computed才会重新执行计算函数;否则直接返回上次结果,举个直观例子:

const count = ref(0)
const double = computed(() => count.value * 2)
const triple = computed(() => double.value * 1.5)

这里double依赖counttriple依赖double,当count0变到1时,double先更新(变成2),然后triple也会更新(变成3),但如果有个和double无关的变量(比如const name = ref('vue')),修改name时,doubletriple都不会重新计算——因为它们的依赖没变化。

另外要注意:如果发现“computed没更新”,大概率是依赖项没被正确跟踪,比如在computed里用了非响应式数据(普通变量,不是refreactive),或者用了异步操作(异步里的响应式数据变化,computed没法实时跟踪),这时候得检查依赖是不是真响应式,或者换watch处理异步场景~

computed能传参数吗?

官方里computed默认是“返回一个值”,不能直接传参,但实际开发中,经常需要“根据参数过滤数据”这类需求——这时候可以computed返回一个函数,比如过滤列表里包含关键词的项:

const list = ref(['vue3', 'react', 'angular'])
const filterList = computed(() => {
  return (keyword) => {
    return list.value.filter(item => item.includes(keyword))
  }
})

然后在模板里这么用:{{ filterList('v') }} → 会返回包含'v'的项(比如'vue3'),但要注意:这种写法缓存机制会失效——因为每次调用filterList('xxx')都是执行内部返回的函数,computed本身的缓存只针对“返回函数”这个操作,函数内部逻辑每次调用都会执行,所以这种场景适合“参数变化不频繁、逻辑简单”的情况;要是参数频繁变化,建议用methods或单独写函数处理~

开发小技巧总结

最后唠几个实际开发里的实用技巧:

  • 别在computed里做异步操作副作用(比如修改其他响应式数据)。computed设计是“纯计算”,做副作用容易让依赖追踪混乱,这种情况用watch更稳妥。
  • 计算逻辑特别复杂时,拆成多个小computed,比如处理用户信息,拆成fullNameageRangeaddressInfo等多个计算属性,既好维护,又能利用缓存(每个小computed只跟踪自己的依赖)。
  • 调试computed时,可把计算函数逻辑临时放到methods里手动调用,快速排查是依赖还是逻辑本身的问题。

Vue3的computed像个“聪明的计算器”:自动跟踪依赖、缓存结果、还支持读写操作,理解它和methods的区别、缓存机制、复杂场景写法,才能在项目里用得顺手,既提性能又让代码更简洁~

版权声明

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

热门