Vue3 computed 和普通函数有什么区别?
先理解原理和示例,再练习完整口述与追问。
回答要点
computed 根据响应式依赖追踪和缓存派生值;普通函数被调用时执行。getter 保持无副作用;可写 computed 通过 setter 明确将更新映射到源状态,不是额外复制一个状态。
原理拆解
computed 把一个纯派生计算包装成可追踪、可缓存的响应式值,依赖变化后在合适的后续读取中重新计算。普通函数没有这种跨读取缓存,但更适合带参数的计算或明确的动作。computed 的输出若是每次新建的大对象,即使值语义相同,也可能给下游造成新引用,性能仍需结合使用方式判断。
示例与推演
const price = ref(10)
const count = ref(2)
const total = computed(() => price.value * count.value)
console.log(total.value, total.value) // 20 20,依赖未变可复用
count.value = 3
console.log(total.value) // 30
需要 totalByTax(rate) 这样的动态参数时,可以保留方法,或在明确条件下建立不同派生值,不能把 computed 当任意参数缓存函数。
易错点
computed 中不应发请求、修改其他响应式状态或把 async Promise 当已经解析的值。读取 Date.now 等非响应式输入不会自动安排下一次更新。
参考回答可直接练习口述
computed 是对响应式依赖的纯派生,读取时按依赖是否失效决定是否重新计算;普通函数在每次调用时执行。我会用 computed 表达过滤、合计、格式化等结果,而不是发请求或改其他状态。可写 computed 的 setter 是把外部赋值映射成源状态的明确规则,并不是另存一份独立状态。
面试官可能继续问追问与完整解答展开收起
追问
排序时直接对源数组调用 sort 有什么影响?异步请求适合放 computed 吗?
追问回答
直接对源数组 sort 会原地修改源状态,在 computed 中这样做可能引入副作用;可先复制再排序。异步请求有等待、取消、失败等过程,不适合用 computed 承载,应通过 watcher、事件或数据获取层维护状态。