computed、watch、methods 怎么选?
先理解原理和示例,再练习完整口述与追问。
回答要点
computed 适合由依赖推导的结果,并按响应式依赖缓存;watch 适合变化触发请求等副作用;methods 是显式调用。计算属性通常保持纯计算,不在其中写状态或发请求。
原理拆解
computed 是由响应式输入派生出的值,通常惰性求值并缓存,依赖变化后失效;methods 是每次调用执行的普通方法;watch 在指定值变化时执行副作用,适合请求、存储和与外部系统同步。选择依据是“我要得到一个值,还是执行一件事”,不是某种写法更高级。computed 的 getter 应尽量纯,避免修改依赖造成循环。
示例与推演
computed: {
total() { return this.rows.reduce((n, row) => n + row.price, 0) }
},
watch: {
keyword(value) { this.loadSuggestions(value) }
}
模板多处读取 total 可以复用缓存;keyword 变化触发请求则是副作用。watch 还需根据业务处理防抖、取消与旧响应,不能只写一个 async 回调就认为完整。
易错点
Date.now 不是响应式依赖,放 computed 中不会自行每秒更新。deep watch 的嵌套修改中,新旧对象经常是同一引用;要比较历史快照,需要主动保存业务所需副本。
参考回答可直接练习口述
我按数据用途区分:由已有状态算出的展示结果用 computed,例如筛选后的列表;变化后要发请求、记录日志等副作用用 watch;点击触发或需要传参的操作用 methods。computed 会收集响应式依赖,在依赖失效后重新计算,未失效时可复用缓存。watch 默认不会立即执行,deep 会递归访问对象以收集深层依赖,所以不能为省事对所有大对象都深度监听。
面试官可能继续问追问与完整解答展开收起
追问
deep 为什么有成本?深层对象原地修改,watch 的新旧值为什么可能相等?Date.now() 为什么不自动让 computed 更新?
追问回答
深度监听需要遍历可访问的嵌套属性,有时间和依赖维护成本。对象原地变化时,新旧参数可能指向同一个对象,它不自动保存修改前快照。Date.now() 不是响应式依赖,只读取它的 computed 不会随时间自动失效,需要定时更新一个响应式时间值。