前言
最近在深入的学习研究vue,其实vue在使用上入门并没有什么太高的门槛,但前端同学们也不该仅仅停留在使用上。以 vue 设计、编码之优秀,足当抽丝剥茧,扒开它的外壳,深入其原理。让我们一起来刺破 vue 的心脏,下面话不多说了,来一起看看详细的介绍吧。
vue核心执行过程图
vue核心的执行过程主要分为这几个阶段:
1) 编译模板,生成可复用的render function code(这是今天要重点解读的),这一步在vue实例的整个生命周期中只会执行一次甚至零次,因为我们可以在打包的时候可以预编译
2) 生成watcher等核心渲染监听,在整个vue实例的生命过程中持续发生着作用,对view和modal进行双向绑定
3) 虚拟dom的diff比较,当watcher监听到data的变更的时候,就会根据注入新的data执行render function code,生成新的虚拟dom,跟老的虚拟dom(第一次执行的时候可能为空)进行diff比对,不同的部分将写入真实的dom
这几个过程都会以源码解析的方式分篇解读,今天我们重点讲解的是第一部分模板编译中输出的render function code
render function code解析
一、模板编译过程分解
// 生成ast语法树 const ast = parse(template.trim(), options) // 标记静态内容(以免diff的时候需要重复比较) optimize(ast, options) // 生成render function code const code = generate(ast, options)
很遗憾,上诉三步的代码今天都只是点到为止,不需要太努力,就能在网上搜到相关解析的文章,如果实在找不到同时又感兴趣,可以找到vue源码中的下面文件去读:
// 编译入口 src/compiller/index.js // html解析 src/compiller/parser/html-parser.js // src/compiller下的其它文件
换一个姿势读源码,今天我们要读的是generate(ast, options)
生成的render function code的具体代码
二、写一个 vue demo
之前有提到过,读源码需要先了解整体的设计思想、架构,上面那个执行过程图在此列;另外,搭建一个demo执行环境进行debug单步调试,也是一个重要手段(特别是你对源码的目录结构不是特别清晰的时候)。为了让生成的render function code更为完整,写一个覆盖面尽量广的 demo :
//template <div id="app"> <p>普通属性:{{ message }}</p> <p>{{msg()}}</p> <p>{{ct}}</p> <input v-model="message"> <div v-for="item in items"> {{ item.text }} </div> <button v-on:click="bindClick">点我抓同伟</button> </div> // js new Vue({ el: '#app', data: { message: '以vue的名义', items: [{ text: '达康书记' }, { text: '育良书记' }] }, methods: { bindClick: function() { this.message = '这就抓同伟去'; }, msg: function() { return this.message + "这个方法每次都会执行"; } }, computed: { ct: function() { return this.message + "计算属性并不会每次都执行"; } } })
render function code 解析
debug 拿到生成的 render function code(当然也可以通过 webpack 的 vue-loader 编译之后的 dist 文件拿到,此处省略1000字)
with(this) { return _c('div', { attrs: { "id": "app" } }, [_c('p', [_v("普通属性:" + _s(message))]), _v(" "), _c('p', [_v(_s(msg()))]), _v(" "), _c('p', [_v(_s(ct))]), _v(" "), _c('input', { directives: [{ name: "model", rawName: "v-model", value: (message), expression: "message" }], domProps: { "value": (message) }, on: { "input": function($event) { if ($event.target.composing) return; message = $event.target.value } } }), _v(" "), _l((items), function(item) { return _c('div', [_v("\n\t\t " + _s(item.text) + "\n\t ")]) }), _v(" "), _c('button', { on: { "click": bindClick } }, [_v("点我出奇迹抓同伟")])], 2) }
甭看这段代码有点怪,但是如果告诉你,这段代码,注入 data 执行,生成的就是传得玄乎其玄的虚拟 dom 树,然后再来一本正经的解(cai)读(ce)一下,你又会觉得这段代码其实没有这么晦涩难懂。ok,结合 demo
来看看,模板相关指令都被解析成什么了:
1) {{messge}}
解析成了 _s(message)
,果断认为这个 _s 就是 toString
2) {{msg()}} method
解析成了 _s(msg())
,可见每一次 render, msg 方法都会被执行一遍(即使最终没有被反应到真实 dom 上),这就是计算属性存在的意义
3) {{ct}}
计算属性依然被解析成了 _s(ct)
,虽然计算属性可以称之为属性,但是形式上毕竟还是方法,是不是觉得比较奇怪?其实 watcher 除了监听组件,还会监听计算属性依赖的属性,一旦属性发生变更,就会执行计算属性方法,并将执行结果赋值给实例作用域下与计算属性方法名相同的属性,这就是直接使用 _s(ct)
而不是 _s(ct())
就能正确引用计算属性值的原因,计算属性快就快在了这里
4) v-for="item in items"
被解析成了
_l((items), function(item) { return _c('div', [_v("\n\t\t " + _s(item.text) + "\n\t ")]) })
可见 _l 跟 for-each 很类似
5) 至于 v-on:click
则解析成了
_c('button', { on: { "click": bindClick } }
6) 再来看看 _c, c->create->createNode
, 假设这个方法就是创建虚拟节点,回头看上述代码,是不是挺有道理,_c 创建根节点,传入的子节点同样需要这个方法创建。找找源码验证下 src/core/vdom/vnode.js,以下中文注释是我加的
constructor ( tag"color: #ff0000">总结以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】
- 谭咏麟.2022-倾·听【环球】【WAV+CUE】
- 4complete《丛生》[320K/MP3][85.26MB]
- 4complete《丛生》[FLAC/分轨][218.01MB]