《Vue进阶教程》第二十九课:立即执行的回调

发布于:2025-02-11 ⋅ 阅读:(33) ⋅ 点赞:(0)

 往期内容:

《Vue进阶教程》第十八课:避免死循环

《Vue进阶教程》第十九课:computed初步实现

《Vue进阶教程》第二十课:lazy懒执行

《Vue进阶教程》第二十一课:支持缓存

《Vue进阶教程》第二十二课:自定义更新(调度器)

《Vue进阶教程》第二十三课:渲染计算属性的结果

《Vue进阶教程》第二十四课:优化

《Vue进阶教程》第二十五课:watch基本概念

《Vue进阶教程》第二十六课:实现侦听函数

《Vue进阶教程》第二十七课:实现侦听对象

《Vue进阶教程》第二十八课:实现新旧值

默认情况下, watch中的回调是不执行的. 但是可以通过传入参数让其立即执行

第一次立即执行回调时, 拿到的旧值是undefined

基本使用

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./vue.js"></script>
  </head>
  <body>
    <script>
      const { reactive, watch } = Vue

      const state = reactive({ name: 'xiaoming', address: { city: '武汉' } })

      watch(
        () => state.name,
        (newValue, oldValue) => {
          console.log('设置immediate选项会立即执行回调')
          console.log(newValue, oldValue)
        },
        { immediate: true }
      )

      setTimeout(() => {
        state.name = 'xiaopang'
      }, 1000)
    </script>
  </body>
</html>

具体实现

立即执行的函数和更新时执行的函数本质上是没有区别的

因此, 我们可以将scheduler封装起来

function watch(source, cb, options = {}) {
  let getter
  if (typeof source == 'function') {
    getter = source
  } else {
    getter = () => traverse(source)
  }
  let oldValue, newValue
  const job = () => {
    newValue = _effect.run()
    cb(newValue, oldValue)
    oldValue = newValue
  }
  const _effect = effect(getter, {
    lazy: true,
    scheduler: job,
  })

  if (options.immediate) {
    job()
  } else {
    oldValue = _effect.run()
  }
}


网站公告

今日签到

点亮在社区的每一天
去签到