写了一个小白都能看懂的 Virtual DOM 实现 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
thomasyim
V2EX    程序员

写了一个小白都能看懂的 Virtual DOM 实现

  •  2
     
  •   thomasyim
    cyan33 2018-03-25 01:15:47 +08:00 5424 次点击
    这是一个创建于 2837 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不知不觉已经是 2018 年了,从接触 React 开始也两年了,但是一直没有勇气深入研究源码。

    然而去年有幸拿到了 FB 的实习,所以给了自己一个强迫去学习的理由。一个月硬读下来,感觉还是很有收获的。

    学习过程中边写博客边重复造轮子,写了两个项目。

    第一个是 learn-react-source-code,是我在 Paul 2016 年 React Rally Talk 上的 build react from scratch 的基础上做了一部分简化、改进后写的一个项目,同时我也(很认真地)写了 6 篇博客,讲了一下我对核心部分的理解。

    第二个是 v-dom,用不到 200 行代码实现了一个 Virtual DOM。Virtual DOM 这个名字让我一开始望而生畏,但是在真正学习理解之后,发现它其实就是一个非常简洁的映射思路。我相信只要有基本的 JS 基础,大家在一定时间内都能读懂这个项目的代码。

    从很多朋友那里已经收到了对这两个项目还不错的评价,所以才斗胆来分享一下,祝大家读完有所收获。

    同时也宣传一下自己在知乎的专栏

    求个 Star。

    以上。

    20 条回复    2018-03-27 12:02:43 +08:00
    TabGre
        1
    TabGre  
       2018-03-25 06:33:41 +08:00 via iPhone   1
    厉害,跟进学习
    hardman
        2
    hardman  
       2018-03-25 07:41:51 +08:00 via Android   1
    了解学习下
    xuanyuanaosheng
        3
    xuanyuanaosheng  
       2018-03-25 08:06:36 +08:00 via Android
    学习一下
    binux
        4
    binux  
       2018-03-25 08:23:52 +08:00
    于是我每次在 ul 列表中,交替 prepend 一个 text node 一个 li,就能导致你的 v-dom 不断 replace 整个 ul 了吗?
    thomasyim
        5
    thomasyim  
    OP
       2018-03-25 08:49:25 +08:00
    @binux 是的 minimal update。这一点你可以在每次 setState 的时候看审查元素,只有“在变动”的元素在变化
    xor
        6
    xor  
       2018-03-25 09:05:30 +08:00 via iPhone
    minimum update 需要 tree diff 算法,光这个算法就不只 200 行了吧
    binux
        7
    binux  
       2018-03-25 09:16:19 +08:00
    @thomasyim 本来只要在 ul 里 prepend 一个元素就可以了,你现在把整个 ul 都重建了,这也叫 minimal update ?
    lance6716276
        8
    lance6716276  
       2018-03-25 10:06:35 +08:00 via Android
    老哥啊,你还上 v2ex
    qiuyk
        9
    qiuyk  
       2018-03-25 10:54:37 +08:00
    之前我闲的蛋疼也写了一个 23333 https://github.com/Siubaak/kut
    qiuyk
        10
    qiuyk  
       2018-03-25 11:05:27 +08:00
    @binux 个人觉得其实算是 react 一个没做好的地方(当然楼主的做法参考了 react ),就是十分不建议在列表头部插入一个元素,会引起之前所有节点的移动。
    ahonn
        11
    ahonn  
       2018-03-25 11:50:13 +08:00
    @qiuyk #10 你知道列表项的 key 是干嘛用的么..
    qiuyk
        12
    qiuyk  
       2018-03-25 12:19:49 +08:00
    @ahonn 知道的 你可以先看下这篇文章 https://zhuanlan.zhihu.com/p/20346379 react 的做法我叫前向 diff 我自己实现加入了后向 diff 并取前向 diff 和后向 diff 的 patches 较小值来更新节点 就不会有这个问题
    thomasyim
        13
    thomasyim  
    OP
       2018-03-25 13:00:24 +08:00 via iPhone
    @binux 我并没有重新 mount 呀:)
    thomasyim
        14
    thomasyim  
    OP
       2018-03-25 13:00:34 +08:00 via iPhone
    @lance6716276 哈哈哈哈哈哈哈
    thomasyim
        15
    thomasyim  
    OP
       2018-03-25 13:01:25 +08:00 via iPhone
    @lance6716276 哈哈哈哈哈哈哈是你
    thomasyim
        16
    thomasyim  
    OP
       2018-03-25 13:27:15 +08:00 via iPhone
    @qiuyk
    binux
        17
    binux  
       2018-03-25 13:30:15 +08:00 via Android
    @thomasyim 你都 replace 了,还说没有
    thomasyim
        18
    thomasyim  
    OP
       2018-03-25 13:33:34 +08:00 via iPhone
    @binux 麻烦你自己好好读代码 再不然就 console 一下再来说好吗? element type 不变的话 是不会进那个 flow 的
    binux
        19
    binux  
       2018-03-25 13:55:58 +08:00 via Android
    @thomasyim 我都说了交替插入 text node 和 li
    thomasyim
        20
    thomasyim  
    OP
       2018-03-27 12:02:43 +08:00
    @binux 不好意思之前没理解你说的什么意思。你说的这个问题即使是在 React 也确实是存在的,直接去看 [React Reconcilliation]( https://reactjs.org/docs/reconciliation.html) 就会有答案。这也是 @qiuyk 上面评论里说的问题。从这个意义上来说 确实不是 minimal update
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4597 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 44ms UTC 05:38 PVG 13:38 LAX 21:38 JFK 00:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86