挂载dom和动态数据更新
1. 前言
来看这里的想必是看过 前文 的,在 前文 ,我们事先了一个简单的 虚拟dom,但是这一dom显然尚未实现挂载的功能,并且还没有实现一些基本的动态数据更新,不过这并不要紧在本文中,我将会带领大家实现一个基本的单项数据更新方法以及一个将dom直接渲染成dom的方法(还未实现 虚拟dom diff算法)
2. 遍历dom以及生产dom
对于遍历dom的算法常见的也就是图论中经典的 深度优先算法 和 广度优先算法,在本文中的深度和广度算法基本依赖于 广度优先算法,深度优先算法的javascript实现。
在原文中,1提到了对多叉树的遍历基本实现如下
本着有轮子坚决不自己写的觉悟,我直接抄袭了这段,魔改了一下后完成了对dom的实现
接着让我们看看渲染的结果吧
ok很不错基本满意,但是显然花括号和属性绑定并没有完整的实现,所以下面需要实现的是数据的单项绑定
3. 一个粗糙的单向数据流实现
3.1 数据到视图
首先我们不考虑性能,至于v-for这样的东西也暂时不去考虑单单考虑存在前缀:xxxx,@xxx以及在文本内容中 {{}}
这两个符号绑定的数据元素,基于此首先要对root元素绑定上scope在渲染dom的阶段取出scope中的数据,来实现对实际数据的封装。
这样我们就需要思考以下两点了:
- 怎样判断模板中的
{{}}
实现?
- 怎么判断props是绑定属性以及@绑定事件?
首先我并没有绝大部分框架制作者深厚的js功底,对于语法分析能力也不是太强,基于此,我直接更加简单的实现一个渲染策略
- 对于模板字符串,那我就简单的认为不允许表达式的使用(如果要使用其实可以使用eval来实现,但这实在太危险了,我并不认为自己能良好的驾驭),这样只需要对某个对象的某个属性或者元素来使用,这样就显得简单的多了。
- props的判断则简单的多,因为显然,只需要判断key的开头是不是规定的元素即可。
让我们一步步实现他吧!
首先假定我们的scope结构是这样的
我们假定我们的模板字符串长这样
3.1.1 模板字符串的渲染
显然的我们需要取出对象里面的方法,具体我不知道有什么更好的方法,这里我就暂且先用这个替代吧!
接着小小魔改一下text阶段的内容即可,这样内容就生效了
3.1.2 属性和事件监听的渲染
让我们看看效果如何
3.1.3 结果!
dom 结构
![dom结构][https://cdn.iceprosurface.com//upload/md/2022/05/22/MwCPEk-WbraTZ.jpg]
试试点击!
看看效果还不错!
但这并不完整,我们只是单单制作了从数据渲染到dom的方法,却没有制作动态的更新策略,下面我们需要作出 dom → data → view
3.2 视图 到 数据 到 视图
当然咯这里我们可以使用最简单的一个实现,那就是使用data的get方法和set方法来操作最简单的那就是直接使用手动设置比如这样
__
是的这样就实现了一个最简单也是最容易实现的监控方法了,但是这样也带来不少问题
4. 问题
4.1 冗长的函数
不难发现随着编写的时间延长,我们的代码行数越来越长,越来越难以控制,方法没有形成模块,查找方法越来越困难
4.2 没有形成组件
这里我们还是在手工绑定对象,手工执行内容,这不合理,我们需要一个工厂自动化处理这些,对了我们需要组件化我们的内容,我们需要组件组件间的交互
4.3 性能低下
不难发现上述更新的过程实际效率非常低,因为显然的假设我们更新了一部分数据,整个页面都会更新,那么假设一次我更新了7-8个数据,那岂不是要整个页面刷新个7-8遍不成?
要知道前端性能的瓶颈主要在dom操作,整个页面的重绘和回流等等都会极大的影响页面速度,而在这之间刷新了7-8遍这是无法接受的,不过好在从开头我们就使用了虚拟dom 那么,接下来需要做的事情就是最小化更新dom以及更加懒惰的更新策略。
5. 结语
下面一章我会尝试将整个js文件拆分解体,使用一些打包合并工具,此外还会尝试对dom的更新作出修改,接下来还会实现一个组件生产器。