如何实现 React 中的虚拟 DOM (上)

 jangwoo 小马学编程  2月16日

React是Facebook开发的一款JS库,注意他不是框架而是库。Facebook 推出 React 主要是为了解决什么问题。

由于当项目变得无比庞大,结构相当复杂时,MVC很快变得非常复复杂,每次添加一项新的功能或特性时,系统的复杂度就成级数增长,致使代码变得脆弱和不可预测,这时 MVC 显得力不从心,无法应付。认为MVC不适合大规模应用,当系统中有很多的模型和相应的视图时,其复杂度就会迅速扩大,非常难以理解和调试,特别是模型和视图间可能存在的双向数据流动。

为了解决这个问题推出“以某种方式组织代码,使其更加可预测” flux 和 react(以组件为基础)。

DOM 和 virtual DOM 

DOM, (Document Objecet Model), 文档对象模型,DOM定义了访问HTML或是XML文档的标准,是一种使程序动态的访问,更新HTML文档或XML文档等的内容,结构以及样式的平台,操作接口,DOM定义了文档的对象和属性,以及访问它们的接口。

Virtual DOM

VirtualDOM,虚拟DOM对象,是 React中的DOM对象。React使用JSX编写虚拟DOM对象,经过Babel编译之后会生成真正的DOM. 然后会将真正的DOM插入(Render)到页面。

由于更新 dom 成本昂贵,所以我们通过读取 virtual dom 这个低成本的对象,

然后将vitural dom 通过 js 渲染到界面

如果操作 dom 或更新了 dom ,我们可以通过 diff 方法,来对比新旧 virtual dom 后,找出不同地方,然后只更新发生变化的部分。这样来更新 dom 就大大地节省了成本,并且提供良好的用户体验。

目标:通过代码讲解 react 是如何实现  virtual dom 

基本要求:熟悉 javascript 的前端开发人员涵盖内容 JSX 编译;基于 virtual dom 生成真实 dom 节点; diff 和 patch 方法是如何实现的。

由于篇幅有限我们将不会讲解 Event(事件) 组件周期 数据属性  性能和缓存

首先我们将 jsx 编译成 vdom ,然后根据 vdom 生成真实 dom。

我们先创建一个项目,然后初始化项目(npm init -y) 的 package.json 文件。

在项目目录下,创建 index.html 文件 如下图

引入使用 babel 将 index.js 编译后的 compiled.js (主要讲 jsx 文件编程)

main 标签为渲染 virtual dom 的容器。

我们安装所需的库 babel-cli 以及 babel 插件

在 .babelrc 配置文件中配置插件以及参数,有关 pragma 使用方法大家可以在 babel 官网 docs 中找到答案,如果不实用该参数默认值为 React.createElement

我们目录下创建 index.js(这个文件会被编译为 compiled.js)

我们先将要实现的方法一个一个罗列出来,然后再一个一个地去实现他。

view 方法返回一个 virtual dom 对象

如果您熟悉 react 图中的代码应该感觉很亲切吧,对这就是 jsx 格式。将 jsx 中xml 转换 javascript 方法来创建 dom

使用下面命令将 index.js 编译成 compiled.js

我们来修改 h 方法,具体可以看一下注释吧

然后我们 chrome 浏览器的控制台中输入 view() 就可以看到此方法返回一个 VMOD 对象

我们根据view生成 virtual dom 对象创建真实 dom 然后将其渲染到网页。

我们需要对node节点的所有child 应用 createElement 进行递归 node 

这里我们用到 es6 新特性,如果对 es6 新特性感兴趣请观看我的优酷视频

实现为 dom 元素设置属性

到现在为止我们完成第一步将 virtual dom 渲染到界面上

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容