Dom上树和节点改变

176 阅读2分钟

任何数据在上树到页面之前,其实会经历一次叫虚拟dom的环节,虚拟dom就是用简单的js对象来描述这个节点的内容,所以用这样一个js对象的结构tag标签、text的这个属性来描述未来节点,所以vue会先创建虚拟dom,在根据虚拟dom在创建真实的dom节点来.

当数据进行改变时, 根据新的数据再创建新的虚拟dom,vue会将新的虚拟dom跟老的虚拟dom对比(diff),再对比时候会发现不一样的(新的虚拟dom跟老的虚拟dom是一一映射的),将不同的找出来以最小的代价(形象的说可以是做成一个补丁)更新到真实的dom节点中.

为什么不直接创建真实的dom节点进行比较?创建一个真实dom时间比较久,属性比较多.况且真实的dom都创建完了,还比较什么!!!(所以创建真实的dom性价比较低)

新旧虚拟dom是如何比较?新的虚拟dom会跟旧的虚拟dom按照索引值进行比较,如果旧的虚拟dom节点为三个,删除中间的虚拟dom节点时,将会按照索引值进行比较,等到新的虚拟dom节点比较到第二个时,会跟旧的虚拟dom节点第二个进行比较,发现与之不同,进行标记成修改,接着旧的第三个虚拟dom节点,跟新的第三个没有,进行标记删除.如何避免根据索引盲目对比?再循环时候加入key值(一定不能使用index为key值)!!!可避免盲目对比(人工智能)

key:跟踪每个节点的身份,从而重用和重新排序现有元素(提高复用)理想的key值时每项都有的且唯一的id

Vue底层更新原理:vue2中object defineproperty get、set拦截,vue3 中通过pro sei 方案进行拦截,拦截到数据发生改变时,通过vue中的watch,通知所有根节点相关的dom,相关的组件从新渲染,再渲染的时候创建新的dom节点,它本质上是对象,对比老的虚拟节点,再对比的过程中,vue内置了diff算法的东西,diff算法保证最优的效率去对比,最小的代价去更新dom,层级相同才对比,层级不同不对比,按照树的结构按照层级对比。列表中靠key来对比,key一样就复用,key不一样就删了从前的再创建一份新的对比。标签一样对比,组件一样对比。若果再新老对比中发现,名字不一样,不一样会删了从新创建,标签不一样也会删了重新对比。 虚拟dom:vdom,vnode,virtual,dom,virtual node