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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/906080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3+AI

玩一下AI 1. SSE协议 我们都知道tcp,ip,http,https,websocket等等协议,今天了解一个新的协议SSE协议(Server-Sent Events) SSE(Server-Sent Events) 是一种允许服务器…

vscode中Debug c++

在vscode中Debug ros c程序 1 在Debug模式下编译 如果用命令行catkin_make,在输入catkin_make时加上一个参数: catkin_make -DCMAKE_BUILD_TYPEDebug 或者直接修改CMakelist.txt,添加以下代码: SET(CMAKE_BUILD_TYPE "D…

【ROS2】 核心概念6——通信接口语法(Interfaces)

古月21讲/2.6_通信接口 官方文档:Interfaces — ROS 2 Documentation: Humble documentation 官方接口代码实战:https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Single-Package-Define-And-Use-Interface.html ROS 2使用简化的描…

C#里与嵌入式系统W5500网络通讯(2)

在嵌入式代码里,需要从嵌入式的MCU访问W5500芯片。 这个是通过SPI通讯来实现的,所以要先连接SPI的硬件通讯线路。 接着下来,就是怎么样访问这个芯片了。 要访问这个芯片,需要通过SPI来发送数据,而发送数据又要有一定的约定格式, 于是芯片厂商就定义下面的通讯格式: …

SuperYOLO:多模态遥感图像中的超分辨率辅助目标检测之论文阅读

摘要 在遥感影像(RSI)中,准确且及时地检测包含数十像素的多尺度小目标仍具有挑战性。现有大多数方法主要通过设计复杂的深度神经网络来学习目标与背景的区分特征,常导致计算量过大。本文提出一种兼顾检测精度与计算代价的快速准确…

计算机软件的基本组成

计算机软件的基本组成 一, 计算机软件的分类 软件按其功能分类, 可分为系统软件和应用软件 图解 (1)系统软件 系统软件是一组保证计算机系统高效, 正确运行的基础软件, 软件通常作为系统资源提供给用户使用. 系统软件主要有操作系统(OS), 数据库管理系统(DBMS), 语言处理程…

unity开发游戏实现角色筛选预览

RenderTexture通俗解释 RenderTexture就像是Unity中的"虚拟相机胶片",它可以: 捕获3D内容:将3D场景或对象"拍照"记录下来 实时更新:不是静态图片,而是动态视频,角色可以动起来 用作…

Spring源码主线全链路拆解:从启动到关闭的完整生命周期

Spring源码主线全链路拆解:从启动到关闭的完整生命周期 一文看懂 Spring 框架从启动到销毁的主线流程,结合原理、源码路径与伪代码三位一体,系统学习 Spring 底层机制。 1. 启动入口与环境准备 原理说明 Spring Boot 应用入口是标准 Java 应…

SAP RF 移动屏幕定制

SAP RF 移动屏幕定制 ITSmobile 是 SAP 当前将移动设备连接到 SAP 系统的技术基础。它基于 SAP Internet Transaction Server (ITS),从 Netweaver 2004 开始作为 Netweaver 平台的一部分提供。ITSmobile 提供了一个框架,用于为任何 SAP 事务生成基于 HT…

Spark,数据提取和保存

以下是使用 Spark 进行数据提取(读取)和保存(写入)的常见场景及代码示例(基于 Scala/Java/Python,不含图片操作): 一、数据提取(读取) 1. 读取文件数据&a…

如何用mockito+junit测试代码

Mockito 是一个流行的 Java 模拟测试框架,用于创建和管理测试中的模拟对象(mock objects)。它可以帮助开发者编写干净、可维护的单元测试,特别是在需要隔离被测组件与其他依赖项时。 目录 核心概念 1. 模拟对象(Mock Objects) 2. 打桩(Stubbing) 3. 验…

最新缺陷检测模型:EPSC-YOLO(YOLOV9改进)

目录 引言:工业缺陷检测的挑战与突破 一、EPSC-YOLO整体架构解析 二、核心模块技术解析 1. EMA多尺度注意力模块:让模型"看得更全面" 2. PyConv金字塔卷积:多尺度特征提取利器 3. CISBA模块:通道-空间注意力再进化 4. Soft-NMS:更智能的重叠框处理 三、实…

【Linux网络与网络编程】12.NAT技术内网穿透代理服务

1. NAT技术 之前我们说到过 IPv4 协议中IP 地址数量不充足的问题可以使用 NAT 技术来解决。还提到过本地主机向公网中的一个服务器发起了一个网络请求,服务器是怎么将应答返回到该本地主机呢?(如何进行内网转发?) 这就…

uniapp的适配方式

文章目录 前言✅ 一、核心适配方式对比📏 二、rpx 单位:uni-app 的核心适配机制🧱 三、默认设计稿适配(750宽)🔁 四、字体 & 屏幕密度适配🛠 五、特殊平台适配(底部安全区、刘海…

JAVA EE(进阶)_进阶的开端

别放弃浸透泪水的昨天,晨光已为明天掀开新篇 ——陳長生. ❀主页:陳長生.-CSDN博客❀ 📕上一篇:JAVA EE_HTTP-CSDN博客 1.什么是Java EE Java EE(Java Pla…

SQL脚本规范

主要作用:数据库的备份和迁移 SQL脚本规范 每一个sql语句必须与;结束 脚本结构: { 删库,建库 删表,建表 插入初始数据 } 建库语法: CREATE DATABASE 数据库名CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CHARA…

std::ratio<1,1000> 是什么意思?

author: hjjdebug date: 2025年 05月 14日 星期三 09:45:24 CST description: std::ratio<1,1000> 是什么意思&#xff1f; 文章目录 1. 它是一种数值吗&#xff1f;2. 它是一种类型吗&#xff1f;3. std:ratio 是什么呢&#xff1f;4. 分析一个展开后的模板函数5.小结: …

测试--测试分类 (白盒 黑盒 单元 集成)

一、按照测试目标分类&#xff08;测试目的是什么&#xff09; 主类别细分说明1. 界面测试UI内容完整性、一致性、准确性、友好性&#xff0c;布局排版合理性&#xff0c;控件可用性等2. 功能测试检查软件功能是否符合需求说明书&#xff0c;常用黑盒方法&#xff1a;边界值、…

整理了 2009 - 2025 年的【199 管综真题 + 解析】PDF,全套共 34 份文件

每年真题原卷 ✅ 每年详细解析 ✅ &#x1f4c2;【管综真题 2009-2025】 &#x1f4c2;【管综解析 2009-2025】 目录树&#xff1a; ├── 2009-2025管综真题 PDF │ ├── 2009年199管综真题.pdf │ ├── 2010年199管综真题.pdf │ ├── 2011年199管综真题.pd…

用golang实现二叉搜索树(BST)

目录 一、概念、性质二、二叉搜索树的实现1. 结构2. 查找3. 插入4. 删除5. 中序遍历 中序前驱/后继结点 一、概念、性质 二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;简写BST&#xff0c;又称为二叉查找树 它满足&#xff1a; 空树是一颗二叉搜索树对…