vDom和domDiff
虚拟dom和domDiff
1. 构建虚拟DOM
var tree = el('div', {'id': 'container'}, [
el('h1', {style: 'color: blue'}, ['simple virtal dom']),
el('p', ['Hello, virtual-dom']),
el('ul', [el('li')])
])
2. 通过虚拟DOM构建真正的DOM
var root = tree.render()
document.body.appendChild(root)
3. 当数据发生变化,生成新的虚拟DOM
var newTree = el('div', {'id': 'container'}, [
el('h1', {style: 'color: red'}, ['simple virtal dom']),
el('p', ['Hello, virtual-dom']),
el('ul', [el('li'), el('li')])
])
4. 比较两棵虚拟DOM树的不同
var patches = diff(tree, newTree)
5. 在真正的DOM元素上应用变更
patch(root, patches)
难点就在于比较diff
给你两个数组,数组里装着几个对象,对比这两个数组的区别,首先需要考虑的是什么,顺序,也就是复用性,因为dom里有子元素,如果能移动位置,就优先移动位置,对比之后,没有的就删了,在把新的添加就行,但是,但是对比对象的成本非常的高,我要对比两个对象是不是同一个要对比name,对比age,对比很多的值,才能知道这个是原本的第一个值现在变到第三个了,如何减少对比,用key
,用对象里不变的量做对比,因为有key,所以对象级别的对比就变成了字符串数组级别的对比,这也是vue的优化方案之一,如何对比字符串数组的diff,往下看
// 列表对比,主要也是根据 key 值查找匹配项
// 对比出新旧列表的新增/删除/移动
function diffList(oldList, newList, index, pathchs) {
let change = []
let list = []
const newKeys = getKey(newList)
oldList.map(v => {
if (newKeys.indexOf(v.key) > -1) {
list.push(v.key)
} else {
list.push(null)
}
})
// 标记删除
for (let i = list.length - 1; i>= 0; i--) {
if (!list[i]) {
list.splice(i, 1)
change.push({ type: 'remove', index: i })
}
}
// 标记新增和移动
newList.map((item, i) => {
const key = item.key
const index = list.indexOf(key)
if (index === -1 || key == null) {
// 新增
change.push({ type: 'add', node: item, index: i })
list.splice(i, 0, key)
} else {
// 移动
if (index !== i) {
change.push({
type: 'move',
form: index,
to: i,
})
move(list, index, i)
}
}
})
return { change, list }
}
更新
新增的新增,删除的删除的,移动的先移动,再对比移动的数据的标签值的变化,比如值的变化,class的变化,内容的变化等等,之后还要递归执行子一级的变化,才能完成一次domDiff
理想化
上面说的只是理想化的对比,如果我不设置key呢,vue会自己设置,就比如vue的dom上个特殊的id,那vue能自己设置还要我们设置干什么,他设置需要去生成uuid之类的id,是需要成本的
参考资料
domDiff第一篇
domDiff第二篇
domDiff第三篇
domDiff第四篇
domDiff第五篇
domDiff第六篇
domDiff第七篇
vDom和domDiff的更多相关文章
- WebWorker 中将已处理好的 VDOM 数据提交主线程渲染 DOM
上篇文章讲了 WebWorker 的简单用法,其实网上很多类似的文章,我写的也比较垃圾.不会的建议可以网上看比较好点的资料. 这里我会先讲下我的大致思路.然后会贴上一堆不实用的垃圾代码供参考. Web ...
- javascript基础修炼(11)——DOM-DIFF的实现
目录 一. 再谈从Virtual-Dom生成真实DOM 二. DOM-Diff的目的 三. DOM-Diff的基本算法描述 四. DOM-Diff的简单实现 4.1 期望效果 4.2 DOM-Diff ...
- vdom,diff,key 算法的了解
<ul id='list'> <li class='item'>Item1</li> <li class='item'>Item2 </li> ...
- VDOM configuration
VDOM configuration 来源 https://cookbook.fortinet.com/vdom-configuration/ Posted on January 6, 2015 by ...
- 浅谈React和VDom关系
组件化 组件的封装 组件的复用 组件的封装 视图 数据 视图和数据之间的变化逻辑 import React, {Component} from 'react'; export default clas ...
- 谈谈Vue/React中的虚拟DOM(vDOM)与Key值
谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...
- VDOM总结
https://segmentfault.com/a/1190000016129036
- snabbdom vdom 框架
1.snabbdom github地址:https://github.com/snabbdom/snabbdom 2.核心方法 var vnode = h('div#container.two.cla ...
- 逐行剖析Vue源码(一)——写在最前面
1. 前言 博主作为一名前端开发,日常开发的技术栈是Vue,并且用Vue开发也有一年多了,对其用法也较为熟练了,但是对各种用法和各种api使用都是只知其然而不知其所以然,因此,有时候在排查bug的时候 ...
随机推荐
- Python 爬取 热词并进行分类数据分析-[数据修复]
日期:2020.02.01 博客期:140 星期六 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...
- hbase单机版安装
hbase单机版安装 1. hbase单机版安装 HBase的安装也有三种模式:单机模式.伪分布模式和完全分布式模式. hbase依赖于Hadoop和Zookeeper. 这里安装的是单机版 ...
- 攻防世界Web进阶-Upload1
进入题目 题目提示上传文件,准备好一句话木马. 发现只能上传图片文件,那么再准备一个图片的一句话木马.上传. 浏览器开代理,使用burpsuite拦截,修改文件后缀名为php,否则无法连接 使用蚁剑连 ...
- spring boot中的底层配置文件application.yam(application.property)的装配原理初探
*在spring boot中有一个基础的配置文件application.yam(application.property)用于对spring boot的默认设置做一些改动. *在spring boot ...
- Mac安装navigate premium
转自Navicat Premium for Mac v12.0.22.0 破解教程,macOS上手动破解,无需补丁,无毒今天换了电脑,想装一个Navicat,突然发现了这篇破解教程,竟爱不释手,顾Co ...
- Java如何实现序列化,有什么意义?
1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States, 但是Java给你提供一种应该 ...
- 1016 部分A+B (15 分)
正整数 A 的“DA(为 1 位整数)部分”定义为由 A 中所有 DA 组成的新整数 PA.例如:给定 8,DA=6,则 A 的“6 部分”PA 是 66,因为 A 中有 ...
- Community Cloud零基础学习(二)信誉等级设置 & Global Search设定
当我们创建了Community以后,我们需要对他进行定制页面来使community用户更好的使用.此篇主要描述两点,信誉等级设定以及Global Search 设定.其他的内容后期再慢慢描述. 一. ...
- 六、Centos7中配置svn服务器
今天配置了 SVN 记在这儿 备忘: --svn开机自启动服务 systemctl enable svnserve.service --svn开机自启动服务 systemctl disable svn ...
- Ubuntu系统为MySQL开启远程连接
第一步:确保 Ubuntu 系统已经安装上了MySQL数据库.登陆数据库 ,运行如下命令: mysql -u 用户名 -p 然后输入密码,此时登录成功 第二步:创建用户用来远程连接,运行如下命令: G ...