前端八股Vue(7)---computed计算属性和watch侦听器

张开发
2026/4/21 18:05:10 15 分钟阅读

分享文章

前端八股Vue(7)---computed计算属性和watch侦听器
目录一、一句话核心区别二、computed计算属性详解2.1 一句话定义2.2 特点2.3 基本用法2.4 适用场景三、watch侦听器详解3.1 一句话定义3.2 特点3.3 基本用法3.4 watch 的配置选项3.5 适用场景四、核心区别对比表五、实际场景选择指南什么时候用 computed什么时候用 watch六、问答Qcomputed 和 watch 的区别是什么问为什么 watch 监听 reactive 对象时newVal 和 oldVal 相等一、一句话核心区别维度computedwatch核心定位用已有的数据算出一个新的数据监听一个数据它一变就做事情有无缓存✅ 有缓存❌ 无缓存是否 return✅ 必须 return❌ 不需要 return能否异步❌ 不能只能同步✅ 可以发请求、定时器触发时机依赖变化时自动重新计算监听的数据变化时执行二、computed计算属性详解2.1 一句话定义用已有的数据算出一个新的数据。2.2 特点特点说明依赖响应式数据依赖的变量变化时自动重新计算有缓存依赖不变计算结果不变不会重复执行必须 return返回计算后的值只能同步不能写异步代码不能发请求、定时器默认只读也可以写 setter 实现可写2.3 基本用法template div pfirstName: {{ firstName }}/p plastName: {{ lastName }}/p pfullName: {{ fullName }}/p ptotalPrice: {{ totalPrice }}/p pfilteredList: {{ filteredList }}/p /div /template script setup import { ref, computed } from vue const firstName ref(张) const lastName ref(三) const price ref(100) const quantity ref(2) const list ref([1, 2, 3, 4, 5]) // 基本计算拼接 const fullName computed(() { return firstName.value lastName.value }) // 计算属性总价 const totalPrice computed(() { return price.value * quantity.value }) // 数组过滤 const filteredList computed(() { return list.value.filter(item item 2) }) // 可写的计算属性少见但面试可能会问 const writableFullName computed({ get() { return firstName.value lastName.value }, set(newValue) { const [first, last] newValue.split( ) firstName.value first lastName.value last } }) /script2.4 适用场景场景示例数据拼接全名、地址拼接数据计算总价、平均值、数量统计数据过滤筛选列表、搜索过滤数据格式化日期格式化、金额格式化多个数据组合多个条件组合判断三、watch侦听器详解3.1 一句话定义监听一个数据它一变我就做一些事情。3.2 特点特点说明监听变化监听指定数据变化时执行回调无缓存每次变化都会执行不需要 return执行副作用操作可以做异步发请求、定时器、防抖等可以获取新旧值回调参数 (newVal, oldVal)3.3 基本用法template div input v-modelsearchKeyword placeholder搜索关键词 / input v-modeluser.name placeholder用户名 / input v-modeluser.age placeholder年龄 / /div /template script setup import { ref, reactive, watch } from vue const searchKeyword ref() const user reactive({ name: 张三, age: 18 }) // 1. 监听单个 ref watch(searchKeyword, (newVal, oldVal) { console.log(搜索词从 ${oldVal} 变为 ${newVal}) // 防抖搜索请求 const timer setTimeout(() { // 发请求搜索 fetchSearchResults(newVal) }, 500) return () clearTimeout(timer) }) // 2. 监听多个数据数组形式 watch([() user.name, () user.age], ([newName, newAge], [oldName, oldAge]) { console.log(name: ${oldName} → ${newName}) console.log(age: ${oldAge} → ${newAge}) }) //为什么用 () user.name 而不是 user.name // ❌ 错误user.name 是字符串不是响应式数据 //watch([user.name, user.age], (...) {...}) // ✅ 正确用 getter 函数获取响应式值 //watch([() user.name, () user.age], (...) {...}) // 3. 监听 reactive 对象需要深度监听 watch(() user, (newVal, oldVal) { console.log(user 变化了, newVal) }, { deep: true }) // 深度监听 // 4. 立即执行页面初始化时立即执行一次 watch(searchKeyword, (newVal) { console.log(立即执行一次, newVal) }, { immediate: true }) // 5. 异步操作 watch(searchKeyword, async (newVal) { if (!newVal) return const res await api.search(newVal) searchResults.value res.data }) /script3.4 watch 的配置选项选项说明deep: true深度监听对象内部属性变化也能检测到immediate: true立即执行一次页面初始化时就触发flush: postDOM 更新后再执行回调3.5 适用场景场景示例异步请求搜索框输入变化发请求、id 变化重新获取数据复杂逻辑多个数据变化触发复杂业务逻辑DOM 操作数据变化后需要操作 DOM路由监听监听路由参数变化重新加载页面数据防抖/节流输入框防抖搜索四、核心区别对比表对比维度computedwatch本质计算新值监听变化做事情是否有缓存✅ 有依赖不变结果不变❌ 无每次变化都执行是否必须 return✅ 是❌ 否能否异步❌ 否✅ 是是否支持深度监听❌ 否自动收集依赖✅ 是需要 deep: true是否支持立即执行❌ 否懒执行✅ 是immediate: true返回值返回计算值无返回值执行副作用使用方式模板中直接使用监听数据变化执行回调五、实际场景选择指南什么时候用 computed// ✅ 场景1数据拼接 const fullName computed(() firstName.value lastName.value) // ✅ 场景2数据计算 const totalPrice computed(() price.value * quantity.value) // ✅ 场景3数组过滤 const activeUsers computed(() users.value.filter(u u.isActive)) // ✅ 场景4数据格式化 const formattedDate computed(() dayjs(date.value).format(YYYY-MM-DD))什么时候用 watch// ✅ 场景1异步请求 watch(keyword, async (newVal) { const res await api.search(newVal) results.value res.data }) // ✅ 场景2复杂业务逻辑 watch(formData, (newVal) { // 表单变化时校验、保存草稿等 validateForm(newVal) saveDraft(newVal) }, { deep: true }) // ✅ 场景3路由变化监听 watch(() route.params.id, (newId) { fetchDetail(newId) }) // ✅ 场景4DOM 操作 watch(showModal, (newVal) { if (newVal) { // 弹窗打开后聚焦输入框 nextTick(() inputRef.value.focus()) } })六、问答Qcomputed 和 watch 的区别是什么答computed 和 watch 的核心区别在于1. 定位不同computed 是计算属性根据已有数据计算新值必须 returnwatch 是侦听器监听数据变化后执行副作用操作不需要 return2. 缓存机制computed 有缓存依赖不变就不会重新计算watch 没有缓存每次变化都执行3. 异步支持computed 只能同步不能写异步代码watch 支持异步可以发请求、开定时器4. 使用场景computed 适合数据拼接、计算、过滤、格式化watch 适合异步请求、复杂逻辑、DOM 操作、路由监听问为什么 watch 监听 reactive 对象时newVal 和 oldVal 相等答因为 reactive 返回的是 Proxy 代理对象修改的是对象内部的属性而不是对象本身的引用。所以新旧值指向的是同一个 Proxy 对象因此它们全等。如果需要获取真正的旧值应该监听具体的属性而不是整个对象。computed 算新值有缓存必须 return不能异步 watch 做事情无缓存不用 return可以异步 数据拼接用 computed 发请求用 watch 过滤列表用 computed 表单验证用 watch

更多文章