computed 应用于同步推导响应式值,不可赋值、不可含异步逻辑,需基于 ref/reactive 源数据;过滤时须防空与类型安全,搜索高亮等副作用应交由 watch 或模板处理。
直接用 computed,别写成方法或手动缓存,否则失去响应式和性能优势。
computed 必须基于响应式数据,且不能直接赋值
它不是普通变量,而是依赖其他响应式字段(如 ref 或 reactive)动态推导出的只读值。你改不了 fullName.value,只能去改 firstName 或 lastName。
- 错误写法:
fullName.value = 'xxx'→ 运行时报错 “Cannot assign to read only property” - 正确写法:修改源头,比如
firstName.value = 'Li',fullName自动更新 - 在
setup语法糖中,必须用computed(() => ...),不能写成对象形式(那是 Options API 写法)
过滤列表这类场景,记得防空和类型安全
用户输入可能为空、为 null、或字段缺失,直接链式调用 .toLowerCase() 会报错。
- 用可选链
item.name?.toLowerCase()避免Cannot read property 'toLowerCase' of null - 数字 ID 要转字符串再搜:
item.id?.toString().includes(keyword),否则123.includes('2')会报错 - 别用
new RegExp(keyword, 'i')—— 用户输[abc]就触发SyntaxError: Invalid regular expression
computed 不适合发请求、改 DOM、或含异步逻辑
它的作用是“算出一个值”,不是“做一件事”。想发请求或高亮关键词?交给 watch 或模板层处理。
-
computed里写await fetch(...)→ 返回的是Promise,模板显示[object Promise] - 需要搜索后高亮?别在
computed里拼<span></span>字符串,留到 template 用v-html或单独封装高亮组件 - 要监听搜索框变化并拉取远程数据?用
watch(searchText, () => { ... }),加immediate: true控制是否首次执行
最常被忽略的一点:computed 的缓存只对「同步返回值」生效。一旦你在里面写了定时器、setTimeout、或任何异步副作用,缓存机制就失效了,还可能引发竞态问题——这不是 bug,是设计使然。


















