1.Vue源码实现之watcher拾遗
2.详解如何关闭dep数据保护?dep保护是加源什么意思-搜狗输入法
3.实例讲解Debian系的Linux中软件包的安装与管理命令用法
4.Vue—关于响应式(四、深入学习Vue响应式源码)
5.最前端|详解VUE源码初始化流程以及响应式原理
Vue源码实现之watcher拾遗
Vue源码中的源码Watcher类设计精妙,它在响应式原理的加源基础之上,添加了额外的源码处理机制。构造函数中的加源新特性包括两个额外参数:deps和newDeps。它们在数据更新时,源码源码图鉴文件帮助管理watcher与数据的加源依赖关系,确保只在真正需要时重新渲染视图,源码避免不必要的加源性能开销。
在Watcher的源码初始化过程中,get方法至关重要。加源它首先将watcher添加到Dep.target的源码堆栈中,触发依赖的加源收集。当数据属性被读取时,源码依赖对象dep的加源depend方法会被激活,进而将watcher添加到新Deps中。同时,之前的依赖可能会被清理,将不再需要的watcher从旧的依赖列表中移除,只保留最新的依赖,存储在watcher.deps中。
getter的主要作用就是“touch”被监控的数据,以此触发依赖的收集。如果传入的是函数,如渲染watcher的updateComponent,getter会直接调用该函数,遍历并处理所有引用的数据,确保数据变化时能正确响应。
在设置依赖收集标志时,Vue使用pushTarget和popTarget来管理依赖的嵌套。在计算属性的处理中,pushTarget确保依赖收集的正确顺序,让计算属性watcher收集到的依赖只影响到它自身,而popTarget则恢复到之前的渲染watcher状态,以便继续正常的视图更新流程。
总的来说,Vue的Watcher类通过这些机制实现了高效、精准的数据依赖跟踪,确保了响应式系统的稳定和性能。
详解如何关闭dep数据保护?dep保护是什么意思-搜狗输入法
搜狗输入法,作为业界领先的智能输入解决方案,凭借其强大的图片分享源码网站词库、智能化的组词功能和用户友好的界面设计,赢得了亿万用户的青睐。无论是手机还是电脑,搜狗输入法都能提供快速、准确的输入体验。现在您可以轻松下载最新版本的搜狗输入法,享受极致的输入新体验。/
如何关闭dep数据保护
dep是什么呢?可能很多朋友还没听说过这个东西。下面我们就来初步了解一下dep的工作原理以及如何关闭dep数据保护。
DEP 的防病毒原理:
如果你的系统升级到了SP2,启用SP2的DEP功能即可防范病毒破坏,这是因为DEP能够对各种程序进行监视,阻止病毒在受保护的内存位置运行有害代码。DEP通过处理器的NX(No eXecute)功能,查找内存中没有明确包含可执行代码的数据(这些数据有时会是病毒的源代码),找到这些数据后,NX将它们都标记为“不可执 行”。以后如果某程序在内存中,试图执行这些带“不可执行”标记的代码,SP2将会自动关闭该程序。因此,假如你运行了一个已经染毒的软件,DEP就会把病毒代码标记为“不可执行”,这样就能阻止病毒在内存中运行,保护电脑中的文件免受蠕虫、病毒的传染破坏。
如果你想充分发挥DEP的保护功能,除了要把系统升级到SP2之外,你的CPU还必须支持DEP技术。目前常见的位处理器(例如P4 Northwood等)并不支持NX,支持该技术的CPU主要有AMD的位处理器(Athlon 、AMD Opteron),以及Intel的安腾系列CPU、J系列的P4 Prescott,据说nVIDIA、VIA、全美达等公司也计划在其芯片中加入NX技术,不过这些厂商更新NX的步伐过于缓慢,正式推出还有待时日。
彻底关闭dep的做法:
需要对C:\boot.ini文件进行修改,首先你要改变它的免费vc源码下载只读属性,右键单击该文件选择“属性”,然后取消选择“只读”。然后你可以用记事本来对它进行编辑,找到以multi(0)disk(0)开头的条目,在那一行的结尾应该是/fastdetect选项,如果你安装了SP2,就还能看到/noexecute选项,这正是DEP生效的标志。你可以将/noexecute改为/execute,然后重新启动机器。这样就可以关闭数据执行保护 (DEP)机制。
不彻底关闭dep的做法:(推荐)
以管理员或 Administrators 组成员的身份登录才能完成该过程。如果计算机与网络连接,网络策略设置也可能阻止您完成此步骤。要打开“系统属性”,请单击“开始”,指向“设置”,单击“控制面板”,然后双击“系统”。单击“高级”选项卡,然后单击“性能”下的“设置”。 单击“数据执行保护”选项卡。 在“为下列程序之外的所有程序启用 DEP”列表中,执行下列操作之一: 要为程序禁用 DEP,请选中程序名称旁边的复选框,然后单击“确定”。(如果列表中没有显示该程序的名称,请单击“添加”,导航到“Program Files”文件夹,选择该程序的可执行文件(扩展名为 .exe),然后单击“确定”。) – 或者 – 要为程序启用 DEP,请清除程序名称旁边的复选框,然后单击“确定”。
搜狗输入法官网不仅提供了便捷的下载通道,还为用户准备了详尽的使用指南和贴心的客户服务。通过访问 / ,您将进入一个全新的智能输入世界。无论您遇到任何问题或困惑,搜狗输入法官网都将是您最坚实的后盾。立即点击链接,spring 源码爆红开启您的智能输入之旅吧!
实例讲解Debian系的Linux中软件包的安装与管理命令用法
apt-get用法:apt-get [选项] 命令
apt-get [选项] install|remove pkg1 [pkg2 ...]
apt-get [选项] source pkg1 [pkg2 ...]
apt-get 是一个下载安装软件包的简单命令行接口。
最常用的命令是update(更新)
和install(安装)。
命令:
update - 重新获取软件包列表
upgrade - 进行更新
install - 安装新的软件包
remove - 移除软件包
autoremove - 自动移除全部不使用的软件包
purge - 移除软件包和配置文件
source - 下载源码档案
build-dep - 为源码包配置编译依赖
dist-upgrade - 发行版升级, 参见 apt-get(8)
dselect-upgrade - 依照 dselect 的选择更新
clean - 清除下载的归档文件
autoclean - 清除旧的的已下载的归档文件
check - 检验是否有损坏的依赖
选项:
-h 本帮助文件。
-q 输出到日志 - 无进展指示
-qq 不输出信息,错误除外
-d 仅下载 - 不安装或解压归档文件
-s 不实际安装。模拟执行命令
-y 假定对所有的询问选是,不提示
-f 尝试修正系统依赖损坏处
-m 如果归档无法定位,尝试继续
-u 同时显示更新软件包的列表
-b 获取源码包后编译
-V 显示详细的版本号
-c=? 阅读此配置文件
-o=? 设置自定的配置选项,如 -o dir::cache=/tmp
例:
复制代码
代码如下:
apt-cache search packagename搜索包
复制代码
代码如下:
apt-cache show packagename获取包的相关信息,如说明、大小、版本等
复制代码
代码如下:
apt-get install packagename安装包
复制代码
代码如下:
apt-get install packagename - - reinstall重新安装包
复制代码
代码如下:
apt-get -f install修复安装-f = --fix-missing
复制代码
代码如下:
apt-get remove packagename删除包
复制代码
代码如下:
apt-get remove packagename - - purge删除包,包括删除配置文件等
复制代码
代码如下:
apt-get update更新源
复制代码
代码如下:
apt-get upgrade更新已安装的包
复制代码
代码如下:
apt-get dist-upgrade升级系统
复制代码
代码如下:
apt-get dselect-upgrade使用 dselect 升级
复制代码
代码如下:
apt-cache depends packagename了解使用依赖
复制代码
代码如下:
apt-cache rdepends packagename是查看该包被哪些包依赖
复制代码
代码如下:
apt-get build-dep packagename安装相关的编译环境
复制代码
代码如下:
apt-get source packagename下载该包的源代码
复制代码
代码如下:
apt-get clean清理无用的包
复制代码
代码如下:
apt-get autoclean清理无用的包
复制代码
代码如下:
apt-get check检查是否有损坏的依赖
pacman
Pacman 是一个 软件包管理器, 作为 ArchLinux发行版的一部分. 它最早由 Arch Linux 的 Judd Vinet开发. Pacman 可以解决安装过程中的依赖问题,自动下载并且安装所有需要的软件包。Pacman包管理器是Arch Linux的一大亮点。它将一个简单的二进制包格式和易用的构建系统结合了起来。Pacman使得简单的管理与自定义软件包成为了可能,而不论他们来自于官方的Arch软件库或是用户自己创建的
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -h用法: pacman 操作 [...]
操作:
pacman { -h --help} //帮助
pacman { -V --version} //查看版本
pacman { -D --database} 选项 软件包 //pacman管理数据库选项
pacman { -Q --query} [选项] [软件包] //查询安装包
pacman { -R --remove} [选项] 软件包 //删除安装包
pacman { -S --sync} [选项] [软件包] //安装安装包
pacman { -U --upgrade} [选项] 文件 //更新安装包
使用 'pacman { -h --help}' 及某个操作以查看可得的选项
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -D --help用法: pacman { -D --database} 选项 软件包
选项:
--asdeps 标记为非单独指定安装的软件包
--asexplicit 标记为单独指定安装的软件包
--config 路径 指定另外的配置文件
--logfile 路径 指定另外的日志文件
--noconfirm 不询问确认
--noprogressbar 下载文件时不显示进度条
--noscriptlet 不执行安装小脚本
-v, --verbose 循环执行
-- debug 显示除错信息
-r, --root 路径 指定另外的安装根目录
-b, --dbpath 路径 指定另外的数据库位置
--cachedir 目录 指定另外的软件包缓存位置
--arch 架构 设定另外的架构
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -Q --help用法: pacman { -Q --query} [选项] [软件包]
选项:
-c, --changelog 查看某软件包的更新日志
-d, --deps 列出所有作为依赖关系安装的软件包 [过滤器]
-e, --explicit 列出所有单独指定安装的软件包 [过滤器]
-g, --groups 查看某软件包组所属的所有软件包
-i, --info 查看软件包信息 (-ii 查看备份文件)
-k, --check 检查该软件包拥有的文件是否存在
-l, --list 列出被查询软件包的内容
-m, --foreign 列出没有在同步数据库时找到的已安装软件包 [过滤器]
-o, --owns 文件 查询哪个软件包拥有 文件
-p, --file 软件包 从某个软件包而不是数据库查询
-s, --search 搜寻符合指定字符串的已安装本地的软件包
-t, --unrequired 列出所有不被其他软件包要求的软件包 [过滤器]
-u, --upgrades 列出所有可升级的软件包 [过滤器]
-q, --quiet 在查询或搜索时显示较少的信息
--config 路径 指定另外的配置文件
--logfile 路径 指定另外的日志文件
--noconfirm 不询问确认
--noprogressbar 下载文件时不显示进度条
--noscriptlet 不执行安装小脚本
-v, --verbose 循环执行
-- debug 显示除错信息
-r, --root 路径 指定另外的安装根目录
-b, --dbpath 路径 指定另外的数据库位置
--cachedir 目录 指定另外的软件包缓存位置
--arch 架构 设定另外的架构
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -R --help用法: pacman { -R --remove} [选项] 软件包
选项:
-c, --cascade 删除软件包及所有的依赖于此的软件包
-d, --nodeps 略过依赖关系检查
-k, --dbonly 只删除数据库记录,不删除文件
-n, --nosave 同时删除配置文件
-s, --recursive 同时删除 (不会破坏其他软件包的) 依赖关系(-ss也包括单独指定安装的依赖关系)
-u, --unneeded 同时删除不需要的 (且不会破坏其他软件包的) 依赖关系
--print 仅打印目标而不执行操作
--print-format 字符串指定如何打印目标
--config 路径 指定另外的配置文件
--logfile 路径 指定另外的日志文件
--noconfirm 不询问确认
--noprogressbar 下载文件时不显示进度条
--noscriptlet 不执行安装小脚本
-v, --verbose 循环执行
-- debug 显示除错信息
-r, --root 路径 指定另外的安装根目录
-b, --dbpath 路径 指定另外的数据库位置
--cachedir 目录 指定另外的软件包缓存位置
--arch 架构 设定另外的架构
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -S --help用法: pacman { -S --sync} [选项] [软件包]
选项:
--asdeps 作为非单独指定安装的软件包安装
--asexplicit 作为单独指定安装的软件包安装
-c, --clean 从缓存目录中删除旧软件包 (-cc 清除所有)
-d, --nodeps 略过依赖关系检查
-f, -force 强制安装,覆盖存在冲突的文件
-g, --groups 查看某软件包组所属的所有软件包
-i, --info 查看软件包信息
-l, --list 软件库 查看在该软件库中的软件包清单
-s, --search 按照指定字符串查询远端软件库
-u, --sysupgrade 升级所有已安装的软件包 (-uu 可启用降级)
-w, --downloadonly 下载但不安装/升级软件包
-y, --refresh 从服务器下载新的软件包数据库
--needed 不重新安装已经为最新的软件包
--ignore 软件包 升级时忽略某个软件包 (可多次使用)
--ignoregroup 软件包组升级时忽略某个软件包组 (可多次使用)
--print 仅打印目标而不执行操作
--print-format 字符串指定如何打印目标
-q, --quiet 在查询或搜索时显示较少的信息
--config 路径 指定另外的配置文件
--logfile 路径 指定另外的日志文件
--noconfirm 不询问确认
--noprogressbar 下载文件时不显示进度条
--noscriptlet 不执行安装小脚本
-v, --verbose 循环执行
-- debug 显示除错信息
-r, --root 路径 指定另外的安装根目录
-b, --dbpath 路径 指定另外的数据库位置
--cachedir 目录 指定另外的软件包缓存位置
--arch 架构 设定另外的架构
复制代码
代码如下:
[zhangy@BlackGhost ~]$ pacman -U --help用法: pacman { -U --upgrade} [选项] 文件
选项:
--asdeps 作为非单独指定安装的软件包安装
--asexplicit 作为单独指定安装的软件包安装
-d, --nodeps 略过依赖关系检查
-f, -force 强制安装,覆盖存在冲突的文件
-k, --dbonly 添加数据库记录,不安装或保持现存文件
--print 仅打印目标而不执行操作
--print-format 字符串 指定如何打印目标
--config 路径 指定另外的配置文件
--logfile 路径 指定另外的日志文件
--noconfirm 不询问确认
--noprogressbar 下载文件时不显示进度条
--noscriptlet 不执行安装小脚本
-v, --verbose 循环执行
-- debug 显示除错信息
-r, --root 路径 指定另外的安装根目录
-b, --dbpath 路径 指定另外的数据库位置
--cachedir 目录 指定另外的软件包缓存位置
--arch 架构 设定另外的架构
例1:
(1).安装或者升级单个软件包
复制代码
代码如下:
pacman -S mysql(2),有时候在不同的软件仓库中,一个软件包有多个版本(比如extra和community)。你可以选择一个来安装
复制代码
代码如下:
pacman -S extra/mysql(3),步包数据库并且安装一个软件包
复制代码
代码如下:
pacman -Sy mysql例2
删除包
(1),删除单个软件包,保留其全部已经安装的依赖关系
复制代码
代码如下:
pacman -R mysql(2),删除指定软件包,及其所有没有被其他已安装软件包使用的依赖关系:
复制代码
代码如下:
pacman -Rs mysql例3
升级系统
复制代码
代码如下:
pacman -Syu例4
查询包
查询可用安装包
复制代码
代码如下:
pacman -Ss mysql要查询已安装的软件包:
复制代码
代码如下:
pacman -Qs mysql例5
其他用法
清理当前未被安装软件包的缓存
复制代码
代码如下:
pacman -Sc下载包而不安装
复制代码
代码如下:
pacman -Sw mysqlVue—关于响应式(四、深入学习Vue响应式源码)
Vue的响应式系统是一个关键组成部分,通过深入源码理解,我们可以揭示其内部工作原理。首先,让我们简要回顾下Vue响应式实现的简化过程,然后逐步剖析源码,从响应式系统的初始化到Watcher、Dep和Observer的交互,以及装饰者模式的应用。
响应式系统的初始化涉及Vue实例化后调用_init方法,其中包括初始化props、methods等,金牌战法macd源码核心是observe函数,它会创建Observer类的实例,通过遍历对象属性并调用defineReactive$$1来处理数据,使其变为响应式。
Dep类负责收集依赖,Watcher在数据变化时接收通知并进行更新。Watcher的产生有四种情况,它们会在数据绑定或组件挂载时创建。为了优化性能,Watcher的更新会在事件循环的下一次Tick执行,以避免同步更新带来的性能损耗。
Vue中巧妙地运用了装饰者模式,如对数组原型方法的重写,既保持了数据的响应性,又不改变原对象。在源码中,Observer类不仅处理数据,还负责数组方法的重写,通过copyAugment和def函数实现了这一功能。
总的来说,Vue响应式系统利用Observer、Dep和Watcher的协作,以及装饰者模式的灵活运用,实现了数据的高效、动态更新。深入理解这些原理有助于我们更好地编写和优化Vue应用。
参考资源:Vue官网、VUE源码解析文章、Watcher实现详解等。
最前端|详解VUE源码初始化流程以及响应式原理
为大家分享一些实用内容,便于大家理解,希望对大家在 Vue 开发中有所助益,直接进入正题:
Vue 源码的入口是 src/core/instance/index.js,此文件负责在 Vue 的 prototype 上注册函数属性等,并执行 initMixin 中注册的 _init 函数。
继续观察流程,_init 方法代表初始化流程,主要代码如下:
如果是组件,则 _isComponent 为真,其他情况下都会执行 resolveConstructorOptions,该函数将用户设置的 options 和默认 options 合并。随后执行一系列初始化函数,如 initLifecycle 初始化生命周期,initEvent 初始化事件处理机制,initRender 初始化 vnode、插槽及属性等。接下来调用 beforeCreate 钩子函数,然后是 initInjections 和 initProvide 两个与通信相关的组件。
这里涉及到两个熟悉的生命周期函数:beforeCreate 和 created。对比 Vue 流程图,可以明确这两个钩子函数的执行时机。
它们之间实际上差了三个初始化过程。重点是 initState 方法:
在此方法中,如果传入 data 则执行 initData,否则初始化一个空对象。接下来可以看到 computed 和 watch 也是在这里初始化的。
简化后的 initData 代码:
此方法首先判断 data 是否为函数,若是则执行,否则直接取值,因此我们的 data 既可以函数,也可以是对象。然后循环 data 的 key 值,通过 hasOwn 判断属性是否有重复。
isReserved 方法是判断变量名是否以 _ 或 $ 开头,这意味着我们不能使用 _ 和 $ 开头的属性名。然后进入 proxy 方法,该方法通过 Object.defineProperty 设置 get 和 set 将 data 的属性代理到 vm 上,使我们能够通过 this[propName] 访问到 data 上的属性,而无需通过 this.data[propName]。最后执行 observe,如下:
前面都是在做一些初始化等必要的判断,核心只有一句:
从这里开始,我们暂时中止 init 流程,开始响应式流程这条线。在阅读源码时,你总会被各种支线打断,这是没有办法的事情,只要你还记得之前在做什么就好。
Observer 类是 Vue 实现响应式最重要的三环之一,代码如下:
这里介绍一下 def 函数,这是 Vue 封装的方法,在源码中大量使用,我们可以稍微分析一下,代码如下:
可以看到,也是使用了 Object.defineProperty 方法,上文提到过。这是一个非常强大的方法,可以说 Vue 的双向绑定就是通过它实现的。它有三个配置项:configurable 表示是否可以重新赋值和删除,writable 表示是否可以修改,enumerable 表示该属性是否会被遍历到。Vue 通过 def 方法定义哪些属性是不可修改的,哪些属性是不暴露给用户的。这里通过 def 方法将 Observer 类绑定到 data 的 __ob__ 属性上,有兴趣的同学可以去 debugger 查看 data 和 prop 中的 __ob__ 属性的格式。
再说回 Observer,如果传入的数据是数组,则会调用 observeArray,该函数会遍历数组,然后每个数组项又会去执行 observe 方法,这里显然是一个递归,目的是将所有的属性都调用 observe。这个 observe 方法实际上是 Vue 实现观察者模式的核心,不仅是在初始化 data 的时候用到。最终,data 上的每个属性都会走到 defineReactive 里面来,重点就在这里:
这个方法的作用是将普通数据处理成响应式数据,这里的 get 和 set 就是 Vue 中依赖收集和派发更新的源头。这里又涉及到了响应式另一个重要的类:Dep。
在这段代码中,通过 Object.getOwnPropertyDescriptor 获取对象的属性描述符,如果不存在,则通过 Object.defineProperty 创建。这里的 get 和 set 都是函数,因此 data 和 prop 中所有的值都会因为闭包而缓存在内存中,并且都关联了一个 Dep 对象。
当用户通过 this[propName] 访问属性时,就会触发 get,并调用 dep.depend 方法(下面的 dependArray 实际上就是递归遍历数组,然后去调用那个数据上的 __ob__.dep.depend 方法),当赋值更新时,则会触发 set,并调用 observe 对新的值创建 observer 对象,最后调用 dep.notify 方法。
总结起来就是,当赋值时调用 dep.notify;当取值时调用 dep.depend。这个方法的作用就在于此,剩下的工作交给了 Dep 类。
接下来我们可以看一下 Dep 类中做了什么。
这里多贴了一些代码,虽然不属于同一个类,但非常重要。这段代码初始化了一个 subs 数组,这个非常熟悉的数组就是我们经常在 Vue 的属性中看到的,它是一个观察者列表。
前文提到,当 key 的 getter 触发时会调用 depend,将 Dep.target 添加到观察者列表中。这样,在 set 的时候我们才能 notify 去通知 update。
另外,还要提一点,前面在设置 getter 时的代码中有这样一段:
那么既然已经执行了 dep.depend,为什么还要执行 childOb.dep.depend,这又是什么东西呢?
实际上,在数据的增删改查中,响应式的实现方式是不同的。setter 和 getter 只能检测到数据的修改和读取操作,因此这部分是由 dep.depend 来实现的。而 data 的新增删除的属性,并不能直接实现响应式,这部分是由 childOb.dep.depend 来完成的,这就是我们常用的 Vue.set 和 Vue.delete 的实现方式。
接着往下看,我们发现 depend 方法将 Dep.target 推入 subs 中。在上面定义中可以看到,它是一个 Watcher 类的实例,这个类就是响应式系统中的最后一环。
不过,我们暂时不管它,在这里还有一个重要的点:targetStack。可以看到有 pushTarget 和 popTarget 这两个方法,它们遵循着栈的原则,后进先出。因此,Vue 中的更新也是按照这个原则进行的。另外,大家可能注意到,这里似乎没有实例化 Watcher 对象,那么它是在什么地方执行的呢?下文会提到。
Watcher 的代码很长,我们这里只看一小段。当 notify 被触发时,会调用 update 方法。需要注意的是,这部分已经不是在 init 的流程中了,而是在数据更新时调用的。
这里正常情况下会执行 queueWatcher:
可以看到,当 data 更新时会将 watcher push 到 queue 中,然后等到 nextTick 执行 flushSchedulerQueue,nextTick 也是一个大家很熟悉的东西,Vue 当然不会蠢到每有一个更新就更新一遍 DOM。它就是通过 nextTick 来实现优化的,所有的改动都会被 push 到一个 callbacks 队列中,然后等待全部完成之后一次清空,一起更新。这就是一轮 tick。
言归正传,接着来看 flushSchedulerQueue:
实际核心代码就是遍历所有的 queue,然后执行 watcher.run,最后发出 actived 和 updated 两个 hook。
watcher.run 会更新值然后调用 updateComponent 方法去更新 DOM。至此,响应式原理的主体流程结束。说了这么多,其实下面这个流程图就能完整概括。
我们回到 init 的流程,上文中 init 的流程并没有执行完,还差这最后一句:
即通过传入的 options 将 DOM 给渲染出来,我们来看 $mount 的代码。
前面是在获取元素以及进行一系列的类型检查判断,核心就在 compileToFunctions 这个方法上。
看到这个 ast 我们就应该知道这个函数的作用了,通过 template 获取 AST 抽象语法树,然后根据定义的模板规则生成 render 函数。
这个方法执行完之后返回了 render 函数,之后被赋值在了 options 上,最后调用了 mount.call(this, el, hydrating)。
这个方法很简单,就是调用 mountComponent 函数。
这里的流程很容易理解。首先触发 beforeMount 钩子函数,然后通过 vm._render 生成虚拟 DOM(vnode)。这个 vnode 就是常说的虚拟 DOM。生成 vnode 后,再调用 update 方法将其更新为真实的 DOM。在 update 方法中,会实现 diff 算法。最后执行 mounted 钩子函数。需要注意的是,这里的 updateComponent 只是定义出来了,然后将其作为参数传递给了 Watcher。之前提到的 Watcher 就是在这个地方实例化的。
至此,init 的主体流程也结束了。当然,其中还有很多细节没有提到。我也还没有深入研究这些细节,之后有时间会进一步理解和梳理。这篇文章主要是为了自己做个笔记,也分享给大家,希望能有所帮助。如果文中有任何错误之处,请大家指正。
版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。
公众号搜索神州数码云基地,了解更多技术干货。