当前位置: 首页 > news >正文

Vue2 和 Vue3 中 watch 用法和原理详解 - 实践

目录

  • 1. Vue2 中的 watch
    • 1. 基本用法
    • 2. 程序式监听
  • 2. Vue3 中的 watch
    • 1. 组合式 API 用法
    • 2. 选项式 API 用法
  • 3.核心原理分析
    • 1. Vue2 的 Watch 原理
    • 2. Vue3 的 Watch 原理
  • 4. 主要差异对比
    • 1. 差异总结
    • 2. 特性对比
  • 5. 使用建议
    • 1. 性能优化
    • 2. 清理副作用
    • 3. 防抖处理
  • 6.常见问题解答
    • 1. Vue2 和 Vue3 的 watch 混用?
    • 2. 什么时候用 watch,什么时候用 computed?
    • 3. watchEffect 和 watch 的区别?

1. Vue2 中的 watch

1. 基本用法

在 Vue2 中,watch 是一个对象,其键是要观察的表达式,值是对应的回调函数或包含选项的对象。

// 对象写法
export default {
data() {
return {
count: 0,
user: {
name: 'John',
age: 25
}
}
},
watch: {
// 监听基本数据类型
count(newVal, oldVal) {
console.log(`count changed from ${oldVal} to ${newVal}`)
},
// 深度监听对象
user: {
handler(newVal, oldVal) {
console.log('user changed:', newVal)
},
deep: true, // 深度监听
immediate: true // 立即执行
},
// 监听对象特定属性
'user.name': function(newVal, oldVal) {
console.log(`name changed from ${oldVal} to ${newVal}`)
}
}
}

2. 程序式监听

Vue2 也提供了 $watch API,可以在实例的任何地方监听数据变化。

export default {
mounted() {
// 使用 $watch API
const unwatch = this.$watch(
'count',
(newVal, oldVal) => {
console.log(`count changed: ${oldVal} -> ${newVal}`)
},
{
immediate: true,
deep: false
}
)
// 取消监听
// unwatch()
}
}

2. Vue3 中的 watch

1. 组合式 API 用法

Vue3 的 watch 更加灵活,支持监听 ref、reactive 对象、getter 函数等多种数据源。

import { ref, reactive, watch, watchEffect } from 'vue'
export default {
setup() {
const count = ref(0)
const user = reactive({
name: 'John',
age: 25
})
// 监听 ref
watch(count, (newVal, oldVal) => {
console.log(`count changed from ${oldVal} to ${newVal}`)
})
// 监听 reactive 对象
watch(
() => user.name, // getter 函数
(newVal, oldVal) => {
console.log(`name changed from ${oldVal} to ${newVal}`)
}
)
// 深度监听对象
watch(
() => user,
(newVal, oldVal) => {
console.log('user changed:', newVal)
},
{ deep: true }
)
// 监听多个源
watch(
[() => count.value, () => user.name],
([newCount, newName], [oldCount, oldName]) => {
console.log(`count: ${oldCount}->${newCount}, name: ${oldName}->${newName}`)
}
)
// watchEffect - 自动追踪依赖
watchEffect(() => {
console.log(`count is ${count.value}, name is ${user.name}`)
})
return {
count,
user
}
}
}

2. 选项式 API 用法

Vue3 也支持在选项式 API 中使用 watch,与 Vue2 的用法类似。

import { watch } from 'vue'
export default {
data() {
return {
count: 0,
user: {
name: 'John',
age: 25
}
}
},
watch: {
count(newVal, oldVal) {
console.log(`count changed from ${oldVal} to ${newVal}`)
}
},
created() {
// 使用 watch 函数
watch(
() => this.user.name,
(newVal, oldVal) => {
console.log(`name changed from ${oldVal} to ${newVal}`)
}
)
}
}

3.核心原理分析

1. Vue2 的 Watch 原理

Vue2 的 watch 基于响应式系统的依赖收集和派发更新机制。

2. Vue3 的 Watch 原理

Vue3 的 watch 基于 effect 机制实现。

  • 将回调函数包装成一个 effect,当被监听的数据发生变化时,effect 会重新执行。
  • 通过 track 函数进行依赖收集,trigger 函数触发更新。
  • 使用调度器 scheduler 控制 effect 的执行时机,实现异步更新和 flush 选项。

4. 主要差异对比

1. 差异总结

  • Vue2 的 watch 语法较为简单直观,适合选项式 API;Vue3 的 watch 更加灵活,适合组合式 API。
  • Vue3 的 watch 基于 effect 机制实现,提供了更好的性能和更丰富的配置选项。
  • 两者都支持深度监听、立即执行、异步回调等特性,但在语法和使用方式上有所不同。

2. 特性对比

特性Vue2Vue3
API 形式选项式组合式 + 选项式
监听 reactive不支持原生支持
深度监听需要显式配置reactive 对象默认深度监听
多源监听不支持支持监听多个数据源
清理副作用不支持支持 cleanup 函数
性能相对较低基于 Proxy,性能更好

5. 使用建议

1. 性能优化

避免不必要的深度监听,只监听需要的属性。

// Vue3 - 避免不必要的深度监听
const largeObject = reactive({ /* 大量数据 */ })
// 不好的做法
watch(largeObject, () => {
// 任何属性变化都会触发
})
// 好的做法 - 只监听需要的属性
watch(
() => largeObject.importantProp,
() => {
// 只有 importantProp 变化时触发
}
)

2. 清理副作用

Vue3 支持在 watch 中清理副作用,避免内存泄漏。

// Vue3 - 清理副作用
watch(
data,
async (newVal, oldVal, onCleanup) => {
let cancelled = false
onCleanup(() => {
cancelled = true
})
const result = await fetchData(newVal)
if (!cancelled) {
// 处理结果
}
}
)

3. 防抖处理

使用防抖函数避免频繁触发 watch 回调。

import { debounce } from 'lodash-es'
// Vue3 防抖监听
watch(
searchQuery,
debounce((newVal) => {
searchAPI(newVal)
}, 300)
)

6.常见问题解答

1. Vue2 和 Vue3 的 watch 混用?

在 Vue3 的选项式 API 中,可以继续使用 Vue2 风格的 watch 选项,但不建议混用。

2. 什么时候用 watch,什么时候用 computed?

watch 用于执行副作用(如 API 调用、DOM 操作),computed 用于派生数据。

3. watchEffect 和 watch 的区别?

watchEffect 自动追踪依赖,立即执行;watch 需要明确指定监听源,默认懒执行。

通过深入理解 Vue2 和 Vue3 中 watch 的用法和原理,可以更好地根据项目需求选择合适的监听方式,并编写出更高效、可维护的代码。

http://www.jsqmd.com/news/6428/

相关文章:

  • 05-FreeRTOS的内存管理
  • 2025攻丝机品牌最新权威推荐排行榜:聚焦全自动攻丝机,半自动等机型,精选攻丝机实力厂商助企业高效选购
  • ​​AI重构混沌工程:智能韧性守护架构高可用时代已来​
  • 064_尚硅谷_短路与和短路或
  • oppoR9m刷Linux系统: 说明-注意事项-知识点
  • 手机框架材质
  • 2025年陶瓷定制企业最新推荐榜单:涵盖电子陶瓷,氧化铝陶瓷,氧化锆陶瓷,氮化铝陶瓷,结构陶瓷领域!
  • 2025阳台装修品牌推荐榜:优质阳台厂商资质、技术、服务测评及高口碑企业优选指南,浙江多为建筑服务与性价比兼具!
  • 2025 年杭州小程序开发机构最新推荐榜单:覆盖多行业定制需求,助力企业精准选靠谱服务商
  • 2025年杭州软件开发公司最新品牌推荐榜:聚焦技术实力与售后体系的优质服务商精选指南!
  • 湖南省茶陵一中校庆120周年:205班捐款
  • 实用指南:计算机网络-ipv4首部校验原理
  • 2025 年人工智能培训厂家最新推荐排行榜:聚焦人工智能培训合规运营机构、产业适配能力与教学实力深度解析
  • 一种以125kHz低频识别 + 2.4GHz数据传输”的方案,通过频率优势互补,为近距离物联网应用提供了可靠、精准且高效的解决方案
  • 高效做PPT!5个亲测模板网站,10分钟出专业演示 !
  • 【WCH蓝牙系列芯片】-基于CH592开发板——HID_Keyboard中添加读、写、通知的服务属性
  • 2025 年 AI 健康管理厂商最新推荐榜单:覆盖多场景需求,深护智康等优质品牌助力行业升级
  • 虚幻5.6插件添加自定义shader
  • 勒索软件速度危机:AI驱动下的网络安全新挑战
  • 在线考试小程序管理系统:一站式智能考试解决方案,助力多场景高效考核
  • 快微商城小程序管理系统:助力商家搭建高效便捷的新零售平台
  • 2025最新布袋包装厂家推荐排行榜:布袋包装,布袋,手提袋,帆布袋定制,无纺布袋,布袋生产,云南布袋包装,茶叶布袋生产商优选指南
  • KTV 娱乐小程序管理系统:数字化运营新选择,助力行业高效经营
  • 城市电商小程序管理系统:助力商家搭建全渠道数字化经营体系
  • 2025沈阳标识标牌厂家推荐排行榜:聚焦行业产能与技术实力,精选沈阳标识标牌优质企业供订做参考
  • L05_新建springboot项目与新建helloword(菜鸟版)
  • Implicit Neural Representations with Periodic Activation Functions
  • 实用指南:智慧外贸平台|基于Java+vue的智慧外贸平台系统(源码+数据库+文档)
  • ObservableCollection子项属性字段值变化的监听处理
  • 大模型落地实践指南:从技术路径到企业级解决强大的方案