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

解读vue3源码(3)——watch

Vue3的watch底层源码主要是通过使用Proxy对象来实现的。在Vue3中,每个组件实例都会有一个watcher实例,用于监听组件数据的变化。当组件数据发生变化时,watcher实例会触发回调函数,从而更新组件的视图。

Vue3的watch底层源码主要涉及到以下几个部分:

  1. 创建watcher对象
  2. 收集依赖
  3. 触发更新

下面对这三个部分进行详细解读。

  1. 创建watcher对象

在Vue3中,watcher对象是通过watchEffect函数创建的。watchEffect函数接收一个函数作为参数,这个函数就是我们要监听的响应式数据的getter函数。watchEffect函数会在创建watcher对象时立即执行这个函数,并收集响应式数据的依赖。

创建watcher对象的源码如下:

function watchEffect(effect, options) {const watcher = new ReactiveEffect(effect, options)watcher.run()return () => {watcher.stop()}
}

其中,ReactiveEffect是一个类,用来创建watcher对象。run方法会执行传入的函数,并收集依赖。stop方法会停止watcher对象的执行。

  1. 收集依赖

在Vue3中,依赖收集是通过track函数实现的。track函数接收两个参数:响应式数据对象和属性名。它会在getter函数执行时,将当前的watcher对象收集到响应式数据对象的依赖列表中。

track函数的源码如下:

function track(target, key) {if (activeEffect === undefined) {return}let depsMap = targetMap.get(target)if (!depsMap) {targetMap.set(target, (depsMap = new Map()))}let dep = depsMap.get(key)if (!dep) {depsMap.set(key, (dep = new Set()))}if (!dep.has(activeEffect)) {dep.add(activeEffect)activeEffect.deps.push(dep)}
}

其中,targetMap是一个全局的Map对象,用来存储所有响应式数据对象的依赖关系。activeEffect是一个全局的watcher对象,表示当前正在执行的watcher对象。

  1. 触发更新

在Vue3中,更新是通过trigger函数实现的。trigger函数接收两个参数:响应式数据对象和属性名。它会在setter函数执行时,遍历响应式数据对象的依赖列表,依次执行每个watcher对象的run方法,从而触发更新。

trigger函数的源码如下:

function trigger(target, key) {const depsMap = targetMap.get(target)if (!depsMap) {return}const dep = depsMap.get(key)if (!dep) {return}dep.forEach(effect => {if (effect.scheduler) {effect.scheduler()} else {effect.run()}})
}

其中,scheduler是一个可选的参数,表示watcher对象的调度函数。如果存在调度函数,则会先执行调度函数,再执行run方法。

下面是watch底层源码的主要实现步骤:

  1. 创建一个Proxy对象,用于监听数据的变化。

  2. 在Proxy对象的set方法中,触发watcher实例的回调函数。

  3. 在watcher实例的回调函数中,执行用户定义的回调函数,并将新旧值传递给回调函数。

  4. 在回调函数中,执行用户定义的逻辑,例如更新组件的视图。

下面是watch底层源码的简单实现:

function watch(source, callback) {const watcher = {callback: callback,oldValue: null,update() {const newValue = source();if (newValue !== this.oldValue) {this.callback(newValue, this.oldValue);this.oldValue = newValue;}}};watcher.update();return watcher;
}function reactive(obj) {return new Proxy(obj, {set(target, key, value) {target[key] = value;watchers.forEach(watcher => watcher.update());return true;}});
}const data = reactive({ count: 0 });const watchers = [];watchers.push(watch(() => data.count, (newValue, oldValue) => {console.log(`count changed from ${oldValue} to ${newValue}`);
}));data.count++; // count changed from 0 to 1

在上面的代码中,我们定义了一个watch函数和一个reactive函数。watch函数用于创建watcher实例,reactive函数用于创建Proxy对象。当数据发生变化时,Proxy对象的set方法会触发watcher实例的回调函数,从而更新组件的视图。

相关文章:

解读vue3源码(3)——watch

Vue3的watch底层源码主要是通过使用Proxy对象来实现的。在Vue3中,每个组件实例都会有一个watcher实例,用于监听组件数据的变化。当组件数据发生变化时,watcher实例会触发回调函数,从而更新组件的视图。 Vue3的watch底层源码主要涉…...

优秀简历的HR视角:怎样打造一份称心如意的简历?

简历的排版应该简洁工整,注重细节。需要注意对齐和标点符号的使用,因为在排版上的细节需要下很大功夫。除此之外,下面重点讲述几点简历内容需要注意的地方。 要点1:不相关的不要写。 尤其是与应聘岗位毫不相关的实习经历&#x…...

系统集成项目管理工程师——考试重点(三)项目管理一般知识

1.项目定义: 为达到特定的目的,使用一定资源,在确定的期间内,为特定发起人提供独特的产品、服务或成果而进行的一系列相互关联的活动的集合。 2.项目目标: 成果性目标:项目产品本身 约束性目标&…...

为什么医疗保健需要MFT来帮助保护EHR文件传输

毫无疑问,医疗保健行业需要EHR技术来处理患者,设施,提供者等之间的敏感患者信息。但是,如果没有安全的MFT解决方案,您将无法安全地传输患者文件,从而使您的运营面临遭受数据泄露,尴尬&#xff0…...

对项目总体把控不足,项目经理应该怎么办?

公司现状:项目人员紧缺,只有两人了解此项目技术细节,其中一个不常驻现场,另一个是执行项目经理李伟。 项目经理王博是公司元老,同时负责多个项目,工作比较忙,不常驻现场,没有参加过…...

【学习笔记】CF603E Pastoral Oddities

先不考虑数据结构部分,尝试猜一下结论。 结论:一个连通块有解当且仅当连通块的度数为偶数。 然后这题要你最大边权最小。最无脑的方法就是直接上 lct \text{lct} lct。真省事啊 我第一眼想到的还是整体二分。这玩意非常好写。 但是为什么也可以用线段…...

如何使用ESP32-CAM构建一个人脸识别系统

有许多人识别系统使用签名、指纹、语音、手部几何、人脸识别等来识别人,但除了人脸识别系统。 人脸识别系统不仅可以用于安全目的来识别公共场所的人员,还可以用于办公室和学校的考勤目的。 在这个项目中,我们将使用 ESP32-CAM 构建一个人脸识…...

JavaWeb分页条件查询参数特殊字符处理

问题背景 在项目开发过程中,基本都会有列表条件查询,例如用户管理会有通过用户姓名模糊查询用户,课程管理会有课程名称模糊查询课程等等。 而查询过程中如果用户在界面上输入一些特殊字符,例如:%_等等,这…...

ubuntu18服务安装

一、JDK安装 将jdk解压缩到该目录 /opt/ sudo tar -zxvf jdk-8u261-linux-x64.tar.gz -C /opt/ #重命名 cd /opt sudo mv jdk-8u261-linux-x64 jdk_8 修改环境变量 sudo vi ~/.bashrc #在文件最后追加以下文本 #进入编辑器后输入以下指令: #1. G //将光标移到最后一…...

这些使用工具大推荐,现在知道不晚

1.Snip Snip是一款截图软件,它突出的优点就是可以制作滚动截图。 例如:对整个网页进行截图,使用Snip即可轻松获取,无需处理水印。 2.Sleep Cycle 快节奏、高压力的生活导致我们越来越晚睡觉,睡眠质量越来越差。 想提…...

【Java|golang】1048. 最长字符串链

给出一个单词数组 words ,其中每个单词都由小写英文字母组成。 如果我们可以 不改变其他字符的顺序 ,在 wordA 的任何地方添加 恰好一个 字母使其变成 wordB ,那么我们认为 wordA 是 wordB 的 前身 。 例如,“abc” 是 “abac”…...

Hive基础和使用详解

文章目录 一、启动hive1. hive启动的前置条件2. 启动方式一: hive命令3. 方式二:使用jdbc连接hive 二、Hive常用交互命令1. hive -help 命令2. hive -e 命令3. hive -f 命令4. 退出hive窗口5. 在hive窗口中执行dfs -ls /; 三、Hive语法1.DDL语句1.1 创建数据库1.2 两…...

c/c++:栈帧,传值,传址,实参传值给形参,传地址指针给形参

c/c:栈帧,传值,传址,实参传值给形参,传地址指针给形参 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,此时学会c的话, 我所知道的周边的会c的同学&…...

玩元宇宙血亏后 蓝色光标梭哈AI也挺悬

蓝色光标2022年年度报告出炉,巨亏21.75 亿元,其中20.38亿亏损因商誉、无形资产及其他资产减值造成,而在实际亏损业务中,元宇宙占比不小。 蓝色光标在元宇宙领域的布局,主要通过三家子公司实施,分别为蓝色宇…...

生物---英文

标题 前言必学场景词汇及用法鸟类昆虫类哺乳类爬行类情境常用单词鸟类虫类哺乳类两栖类与爬行类分类与动物相关的习语前言 加油 必学场景词汇及用法 鸟类 1bird [b[插图]d] n.鸟bird’s-eye-view[ˈb[插图]dzaɪˌvju]adj.鸟瞰图的a bird’s-eye view鸟瞰a flock of bird…...

ENVI 国产高分2号(GF-2)卫星数据辐射定标 大气校正 影像融合

1.数据 高分2号卫星数据,包含: MSS-1\2多光谱数据,4m分辨率; Pan-1\2全色波段数据,0.8m分辨率。 2.处理软件 ENVI5.3 国产插件下载地址:ENVI App Store (geoscene.cn) 首先下载插件文件; …...

操作系统考试复习——第二章 进程控制 同步与互斥

进程控制一般是由OS中的原语来实现的。 大多数OS内核都包含了两大方面的功能: 1.支撑功能:1)中断处理 2)时钟管理 3)原语操作(原语操作就是原子操作。所谓原子操作就是一个操作中所有动作要不全做要不全不做) 2.资源管理功能:1)进程管理…...

mac gitstats查看git提交记录

一、介绍: 进一步来讲,Gitstats它是一个git仓库分析软件,它可以检查仓库并生成历史数据的统计信息。可以帮助你查看git仓库的提交状态,根据不同维度分析计算,并自动生成数据图表。 官网介绍:http://gitst…...

电脑系统错误怎么办?您可以看看这5个方法!

案例:电脑出现系统错误该如何解决? 【这几天长时间使用我的电脑,导致它的系统出现了错误。有没有小伙伴知道如何解决电脑系统出错的问题?求一个能快速解决的方法。】 电脑系统出现错误是使用电脑时难免会遇到的问题之一&#xf…...

九款顶级AI工具推荐

ChatGPT OpenAI开发的最强对话系统 地址:chat.openai.com ChatGPT能够在同一个会话期间内回答上下文相关的后续问题。其在短时间内引爆全球的原因在于,在网友们晒出的截图中,ChatGPT不仅能流畅地与用户对话,甚至能写诗、撰文、编…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

DiscuzX3.5发帖json api

参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...

游戏开发中常见的战斗数值英文缩写对照表

游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...

FTXUI::Dom 模块

DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

基于 HTTP 的单向流式通信协议SSE详解

SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...