watch的作用是监听数据的变化,当数据发生变化时,执行一个回调函数,它的实现依赖于 Vue 的响应式系统(reactive和ref)
案例
通过以下案例来理解,首先引入reactive、effect、watch三个函数,声明obj响应式数据,接着执行watch函数,第一个参数为监听数据,第二个参数为监听回调,最后两秒后修改obj的name值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../../dist/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
<script>
const { reactive, effect, watch } = Vue
// 1. reactive 构建响应性数据
const obj = reactive({
name: 'jc'
})
// 2. 执行了 watch 函数
watch(obj, (value, oldValue) => {
console.log('watch 触发了')
console.log(value)
})
// 3. 两秒后触发 setter 行为
setTimeout(() => {
obj.name = 'cc'
}, 2000)
</script>
</body>
</html>
doWatch方法
watch函数定义在packages/runtime-core/src/apiWatch.ts文件下:

该函数实际执行的是doWatch方法,它会根据传入的参数( source 和 cb )生成一个监听器
1)根据 source 的类型生成 getter
getter是一个函数,用于获取监听数据的值,根据source的类型:
reactive类型,直接返回sourceref类型,返回source.value- 如果
source是一个函数,getter会执行这个函数
2)定义 job 函数
job是watch的核心逻辑,它会在数据变化时执行,它的主要任务是:
- 获取新的值
newValue - 检查新值和旧值是否不同
- 如果不同,执行回调函数
cb
3)调度器 scheduler
scheduler决定了job的执行时机,Vue 提供了三种调度方式:
sync:同步执行post:在渲染后执行pre:在渲染前执行(默认)
function doWatch(
source: WatchSource | WatchSource[] | WatchEffect | object,
cb: WatchCallback | null,
{ immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
): WatchStopHandle {
// 省略
const instance = currentInstance
let getter: () => any
let forceTrigger = false
let isMultiSource = false
if (isRef(source)) {
// 是否 ref 类型
getter = () => source.value
forceTrigger = isShallow(source)
} else if (isReactive(source)) {
// 是否 reactive 类型
getter = () => source
deep = true // 主动开启 深度监听
} else if (isArray(source)) {
isMultiSource = true
forceTrigger = source.some(s => isReactive(s) || isShallow(s))
getter = () =>
source.map(s => {
if (isRef(s)) {
return s.value
} else if (

最低0.47元/天 解锁文章
1291

被折叠的 条评论
为什么被折叠?



