为什么写这篇vue的分析文章?
对于天资愚钝的前端(我)来说,阅读源码是件不容易的事情,毕竟有时候看源码分析的文章都看不懂。每次看到大佬们用了1~2年的vue就能掌握原理,甚至精通源码,再看看自己用了好几年都还在基本的使用阶段,心中总是羞愧不已。如果一直满足于基本的业务开发,怕是得在初级水平一直待下去了吧。所以希望在学习源码的同时记录知识点,可以让自己的理解和记忆更加深刻,也方便将来查阅。
目录结构
本文以vue的第一次 commit a879ec06 作为分析版本
├── build │ └── build.js // `rollup` 打包配置 ├── dist │ └── vue.js ├── package.json ├── src // vue源码目录 │ ├── compiler // 将vue-template转化为render函数 │ │ ├── codegen.js // 递归ast提取指令,分类attr,style,class,并生成render函数 │ │ ├── html-parser.js // 通过正则匹配将html字符串转化为ast │ │ ├── index.js // compile主入口 │ │ └── text-parser.js // 编译{{}} │ ├── config.js // 对于vue的全局配置文件 │ ├── index.js // 主入口 │ ├── index.umd.js // 未知(应该是umd格式的主入口) │ ├── instance // vue实例函数 │ │ └── index.js // 包含了vue实例的初始化,compile,data代理,methods代理,watch数据,执行渲染 │ ├── observer // 数据订阅发布的实现 │ │ ├── array.js // 实现array变异方法,$set $remove 实现 │ │ ├── batcher.js // watch执行队列的收集,执行 │ │ ├── dep.js // 订阅中心实现 │ │ ├── index.js // 数据劫持的实现,收集订阅者 │ │ └── watcher.js // watch实现,订阅者 │ ├── util // 工具函数 │ │ ├── component.js │ │ ├── debug.js │ │ ├── dom.js │ │ ├── env.js // nexttick实现 │ │ ├── index.js │ │ ├── lang.js │ │ └── options.js │ └── vdom │ ├── dom.js // dom操作的封装 │ ├── h.js // 节点数据分析(元素节点,文本节点) │ ├── index.js // vdom主入口 │ ├── modules // 不同属性处理函数 │ │ ├── attrs.js // 普通attr属性处理 │ │ ├── class.js // class处理 │ │ ├── events.js // event处理 │ │ ├── props.js // props处理 │ │ └── style.js // style处理 │ ├── patch.js // node树的渲染,包括节点的加减更新处理,及对应attr的处理 │ └── vnode.js // 返回最终的节点数据 └── webpack.config.js // webpack配置
从template到html的过程分析
我们的代码是从new Vue()开始的,Vue的构造函数如下:
constructor (options) { // options就是我们对于vue的配置 this.$options = options this._data = options.data // 获取元素html,即template const el = this._el = document.querySelector(options.el) // 编译模板 -> render函数 const render = compile(getOuterHTML(el)) this._el.innerHTML = '' // 实例代理data数据 Object.keys(options.data).forEach(key => this._proxy(key)) // 将method的this指向实例 if (options.methods) { Object.keys(options.methods).forEach(key => { this[key] = options.methods[key].bind(this) }) } // 数据观察 this._ob = observe(options.data) this._watchers = [] // watch数据及更新 this._watcher = new Watcher(this, render, this._update) // 渲染函数 this._update(this._watcher.value) }
当我们初始化项目的时候,即会执行构造函数,该函数向我们展示了vue初始化的主线:编译template字符串 => 代理data数据/methods的this绑定 => 数据观察 => 建立watch及更新渲染
1. 编译template字符串
const render = compile(getOuterHTML(el))
其中compile的实现如下:
export function compile (html) { html = html.trim() // 对编译结果缓存 const hit = cache[html] // parse函数在parse-html中定义,其作用是把我们获取的html字符串通过正则匹配转化为ast,输出如下
更新日志
2024年11月13日
2024年11月13日
- 安雯.1994-想你总是在雨季【音乐家】【WAV+CUE】
- 张国荣.2010-I.AM.WHAT.I.AM.2CD【环球】【WAV+CUE】
- 群星.1991-宝丽金精装国语专辑2CD【宝丽金】【WAV+CUE】
- 群星 -《2024好听新歌(01)》十倍音质 U盘音乐 [WAV分轨][1G]
- 伍佰2004《爱你伍佰年》世纪典藏原音精选台首版 3cd[低速原抓WAV+CUE][2G]
- 张艾嘉1997《滚石24K》24K金碟珍藏版系列[低速原抓WAV+CUE][1.1G]
- 宝可梦大集结开服有哪些免费时装获取 大集结免费时装获取大全
- 宝可梦大集结国服新手宝可梦怎么选 新手公测宝可梦推荐
- 宝可梦大集结国服公测福利获取方法大全 大集结开服福利有哪些
- AminaFigarova-SuiteForAfrica(2024)[24-96]FLAC
- 黑鸭子VS绿色森林2007-男女情歌对唱[首版][WAV+CUE]
- 群星《半个月亮爬上来》[DTS-WAV]
- 日本大雷少女COS赏
- 《怪猎荒野》PS5Pro性能表现一般 外媒:会有专门优化
- 《碟中谍8》首支预告公布!阿汤哥手扒飞机惊心动魄