vue3源码分析 -- watch

watch的作用是监听数据的变化,当数据发生变化时,执行一个回调函数,它的实现依赖于 Vue 的响应式系统(reactiveref

案例

通过以下案例来理解,首先引入reactiveeffectwatch三个函数,声明obj响应式数据,接着执行watch函数,第一个参数为监听数据,第二个参数为监听回调,最后两秒后修改objname

<!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类型,直接返回source
  • ref类型,返回source.value
  • 如果source是一个函数,getter会执行这个函数

2)定义 job 函数

jobwatch的核心逻辑,它会在数据变化时执行,它的主要任务是:

  • 获取新的值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 => isRe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值