头图
关于前端视图更新

前言

接到分享任务后一直比较头疼,不知道分享什么内容,能够把此次分享做的比较好。后来偶然在网上看到一篇文章,非常有启发性,引导我做出了本次的内容

代码地址:(https://codepen.io/collection/DkxpbE

代码写的很精妙,短短一百多行代码,还原出来VUE响应式的核心思想。而我花了很长的时间去阅读这段代码,感慨我和尤雨溪之间的前端水平还是有不少差距的。

image.png
(雷军:诗一样的代码)

分析

vue2在mount(准备阶段)时通过watchEffect(副作用)判断是否初次生成

image.png

是的话就生成DOM解构并通过JS更新到H5中(虚拟DOM)

image.png

否的话就判断前后两次传入的代码,分别判断和更新tag类型,传入的props,判断children(子组件)。并把不同的部分重新渲染。

image.png
image.png

vue2使用Object.defineProperty,通过set劫持数据,使用dep.notify()通知对应watcher(上文的watchEffect),watcher调用_update更新视图

image.png

Dep中负责生成虚拟DOM刷新页面的的Effect(副作用函数)在什么时候监听进去的呢,答案是在首屏加载的时候。Dep和Watcher是一对多的关系,可以同时监听多组watchEffect数据

image.png

一个较为完整的流程图

image.png

总结和展望

官方文档中提到VUE3的object拦截器Object.defineProperty已经替换成了Proxy。在几个小试验之后,我发现Proxy是Object.defineProperty的外层封装,相当于我拦截了你的拦截。网上找了一下资料,发现对比defineProperty优点可能是能拦截数组,新增了delete方法,还有更高的自由度。

上文可以解释为什么VUE2我们在子组件中修改传入的obj,会触发父组件的重新渲染,其实是触发了监听在父组件上的date的set劫持。

可以推测出VUE3中传入子组件的object变成了一份深拷贝的复制品,就不会再触发这个问题了,react同理。(单向数据流思想)

写完这些,感觉对前端框架的理解又深入了,感觉做出自己的前端框架也不是不可能。当然,客观的来说这次讨论的只是前端框架的一小部分原理,其外还有大量的优化和功能没有涉及,实际上只是抛砖引玉,希望能发散出更多对前端框架的思考。

项目代码

https://github.com/Alan1034/vue-update

参考文章

https://mp.weixin.qq.com/s/Dopiz0jgqJiSbhLOLzkQbA
https://www.cnblogs.com/datiangou/p/10144883.html
https://www.cnblogs.com/weblff/p/14144414.html

谢谢观看

陈德立
1 声望0 粉丝

前端开发工程师