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

Vue.js---watch 的实现原理

4.7 watch 的实现原理

watch本质上就是使用了effect以及options.scheduler

定义watch函数:

  // watch函数:传入参数source以及回调函数function watch(source , cb) {effect(() => source.foo,{scheduler(){// 回调函数cb()}})}

watch接收两个参数分别是source和cb

  • source 是一个对象,我们希望监听它的 foo 属性的变化。
  • cb 是一个回调函数,当 source.foo 发生变化时,这个回调函数会被执行。

watch的使用:

    // 使用watch函数watch(obj , () => {console.log('值发生改变')})// 修改响应数据的值,导致回调函数执行obj.foo++

值发生改变

**改为更加通用:**除了foo发生改变,其他的发生改变也可以

修改思路:使用函数对传入的对象循环读取,traverse函数:传入对象以及一个set集合(存储已经访问过的),判断类型,类型过关就进行遍历。

    // traverse:值以及读取放入的setfunction traverse(value , seen = new Set){// 如果要读取的数据是原始值,或者已经读取过了,那么什么都不做if(typeof value !== 'object' || value === null || seen.has(value)){return;}// 暂时仅考虑value是一个对象,遍历valuefor(const k in value){traverse(value[k] , seen);}}// watch函数:传入参数source以及回调函数function watch(source , cb) {effect(// traverse() => traverse(source),{scheduler(){// 回调函数cb()}})}

壮大watch—getter函数:

修改思路:定义一个getter,如果source是函数类型直接使用getter函数,如果不是则递归调取

    // watch函数:传入参数source以及回调函数function watch(source , cb) {// 定义getterlet getter if(typeof source === 'function'){getter = source}else {getter = () => traverse(source)}effect(() => getter(),{scheduler(){// 回调函数cb()}})}

重要功能—新旧值

修改思路:这时候要拿到effect的返回参数,返回参数就是oldval,最核心的改动就是添加了懒加载lazy创建了一个懒加载effect,需要的时候才会执行,在值发生改变时,更新新值和旧值

    // watch函数:传入参数source以及回调函数function watch(source , cb) {// 定义getterlet getter if(typeof source === 'function'){getter = source}else {getter = () => traverse(source)}// 定义新旧值let newVal , oldValconst effectFn = effect(() => getter(),{lazy: true,scheduler(){// 值发生改变会发生,此时就有新值了newVal = effectFn()// 回调函数,传入新旧值cb(oldVal , newVal)// 一定要记得更新旧值oldVal = newVal}})// 调用effectFn就是旧值oldVal = effectFn();}

source以及回调函数
function watch(source , cb) {
effect(
// traverse
() => traverse(source),
{
scheduler(){
// 回调函数
cb()
}
}
)
}


**壮大watch---getter函数:**修改思路:定义一个getter,如果source是函数类型直接使用getter函数,如果不是则递归调取
// watch函数:传入参数source以及回调函数
function watch(source , cb) {// 定义getterlet getter if(typeof source === 'function'){getter = source}else {getter = () => traverse(source)}effect(() => getter(),{scheduler(){// 回调函数cb()}})
}

**重要功能---新旧值**修改思路:这时候要拿到effect的返回参数,返回参数就是oldval,最核心的改动就是添加了懒加载lazy创建了一个懒加载effect,需要的时候才会执行,在值发生改变时,更新新值和旧值
// watch函数:传入参数source以及回调函数
function watch(source , cb) {// 定义getterlet getter if(typeof source === 'function'){getter = source}else {getter = () => traverse(source)}// 定义新旧值let newVal , oldValconst effectFn = effect(() => getter(),{lazy: true,scheduler(){// 值发生改变会发生,此时就有新值了newVal = effectFn()// 回调函数,传入新旧值cb(oldVal , newVal)// 一定要记得更新旧值oldVal = newVal}})// 调用effectFn就是旧值oldVal = effectFn();
}

相关文章:

  • 记录:echarts实现tooltip的某个数据常显和恢复
  • Flink 的任务槽和槽共享
  • Linux进程异常退出排查指南
  • 实战2:利用Python与AI模型实现文本分类
  • 开源项目实战学习之YOLO11:12.1 ultralytics-models-sam-blocks.py源码
  • 【matlab技巧】通过手绘的方法设计二维运动轨迹,附MATLAB程序
  • Java 面向对象详解和JVM底层内存分析
  • ARM-Linux 完全入门
  • 基于朴素贝叶斯与 LSTM 的假新闻检测模型对比分析
  • 面试之 Java 新特性 一览表
  • 前端面经12 函数柯里化
  • 配置git从公网能访问-基于frp
  • 项目复习(2)
  • C语言:gcc 如何调用 Win32 打开文件对话框 ?
  • BERT 进阶:Albert 模型详解与实战
  • RFID系统:技术解析与应用全景
  • MATLAB学习笔记(七):MATLAB建模城市的雨季防洪排污的问题
  • Pandas 掌握Matplotlib基础绘图①
  • Redis——持久化
  • 单细胞转录组(1)
  • 特写|银耳种植“北移”到沧州盐山,村民入伙可年增收4万元
  • 经济日报金观平:促进信贷资金畅达小微企业
  • 嫩黑线货物列车脱轨致1名路外人员死亡,3人被采取刑事强制措施
  • 受贿1.29亿余元,黑龙江省原副省长王一新被判无期
  • 泽连斯基:乌代表团已启程,谈判可能于今晚或明天举行
  • 国家卫健委通报:吊销肖某医师执业证书,撤销董某莹四项证书