vue2源码刨析
手搓vue2源码地址:
gitee地址:https://gitee.com/obsessed-with-summer/vue2-source-code-analysis.git
数据监听:
代码位置:src/observer
发布者订阅者+Object.defineProperty中的get和set实现数据劫持:
ast语法树解析:
代码位置:src/compile
主要是通过这个方法生成render函数,其中包括:html解析为ast语法树,ast拼接为字符串,通过该字符串生成rende函数
1 2 3 4 5 6 7 8 9 | function compileTofunction(el) { //1、将html变成ast语法树 let ast = parseHTML(el); //2、将ast语法树遍历拼接成字符串 let code = generate(ast); //3、将字符串变成render函数 let render = new Function(` with ( this ){ return ${code}}`) return render } |
通过_render生成虚拟dom:
代码位置:src/Vnode
_update时候,触发_renders生成新的虚拟dom,然后调用patch方法进行新旧dom对比。
patch有两个参数,分别是新旧dom:
首先进行以下判断:
- 没有新节点,直接触发旧节点的
destory
钩子 - 没有旧节点,说明是页面刚开始初始化的时候,此时,根本不需要比较了,直接全是新建,所以只调用
createElm
- 旧节点和新节点自身一样,通过
sameVnode
判断节点是否一样,一样时,直接调用patchVnode
去处理这两个节点 - 旧节点和新节点自身不一样,当两个节点不一样的时候,直接创建新节点,删除旧节点
patchVnode做了如下操作:
- 新节点是否是文本节点,如果是,则直接更新
dom
的文本内容为新节点的文本内容 - 新节点和旧节点如果都有子节点,则处理比较更新子节点
- 只有新节点有子节点,旧节点没有,那么不用比较了,所有节点都是全新的,所以直接全部新建就好了,新建是指创建出所有新
DOM
,并且添加进父节点 - 只有旧节点有子节点而新节点没有,就是把所有的旧节点删除,也就是直接把
DOM
删除
两者都有子节点,则通过updateChidren来比较:
通过双指针的方式,进行头头比较,尾部尾部比较,然后交叉比较,最终暴力对比。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现