Zhu xiaohang's blog

虚拟dom && diff算法

虚拟dom && diff算法

1.虚拟dom是什么

​ 它是一个Object对象模型,用来模拟真实dom节点的结构

2.虚拟dom的使用基本流程(前四步骤)

​ 1.获取数据

​ 2.创建vdom

​ 3. 通过render函数解析jsx,将其转换成 vdom结构

​ 4.将vdom渲染成真实dom

​ 5.数据更改了

​ 6.使用diff算法比对两次vdom,生成patch对象

​ 7.根据key将patch对象渲染到页面中改变的结构上,而其他没有改变的地方是不做任何修改的( 虚拟dom的惰性原则 )

3.diff算法是什么

​ 用来做比对两次vdom结构

4.diff算法运行结束后,返回是什么

​ 返回一个key

注意:vue是一个mvvm框架,Vue高性能的原因之一就是vdom

深化:Vue vdom 比较 React vdom 有何不一样?

//需求:有一个变量count的初始值为0,经过一系列的运算,得到10001,然后将结果写入box中

<div class='box'></div>
<script>
	var box = document.querySelect('.box')
	var count = 0
	
	//console.time('a')
	//for(var i=0;i<10001;i++){
	//	count++
	//	box.innerHTML = count      //这里操作了10000次dom
	//}
	//console.timeEnd('a')
///////////////////////////////////////////////////////	
	console.time('b')
	for(var i=0;i<10001;i++){
		count++
	}
	box.innerHTML = count         //正常写法操作一次dom
	console.timeEnd('b')			
	
</script>

结论:1.更少的dom操作会更加减少时间花费,减少性能损耗

​ 2.所以我们应该 先操作数据 再去操作dom

​ 3.由以上结论慢慢的前端将一个新的概念引入在框架中 (这个概念就是虚拟dom)

虚拟dom

所谓的virtual dom,也就是虚拟节点

<script>
	//1.vdom是什么?
	//它是一个Object对象模型,用来模拟真实的dom结构
	//需求:vdom如何模拟真实dom,如果将来我想再增加一个li,里面的内容为:你好
	
	<div class='box'>
		<ul class='list'>
			<li>这里是1903</li>
		</ul>
	</div>
	
	var list = document.querySelect('.list')
	var li = documenr.createElement('li')
	li.innerHTML = '你好'
	list.appendChild(li)            //以上的每一步都操作了dom,真实的dom!
	
</script>

vdom的使用流程

​ 1.获取数据

​ 2.创建虚拟dom

//1.获取数据(ajax,fetch)
	var data = {
		id:1,
		name:'1903'
	}
//2.创建vdom	
	var vdom = {
		tag:'div',
		attr:{
			className:'box'
		},
		content:[
			{
				tag:'ul',
				content:[
					{
						tag:'li',
						content:data.name  //'这里是1903'
					}
				]
			}
		]
	}
	
//3.初次渲染vdom(vdom渲染成 真实dom)
	var div = document.creatElement('div')
	div.calssName = 'box'
	var ul = document.creatElement('ul')
	var li = document.creatElement('li')

//vue中 使用的是一个叫做jsx语法 + render函数
	function render(createElment){
		//vu已经封装好这个方法 就是{{}}可以用的原因
	}
	//但是我们的网页结构一般都是很复杂的,这时候我们使用vdom去模拟dom结构,发现vdom这个对象模型太大了,也  		//太长了,所以我们想,如果能在js中也能够书写dom标签结构那就好了,所以结合了js+xml搞出了一个新的语法	//糖 jsx,用jsx来模拟vdom

//通过render函数解析jsx,将其解析成vdom结构
//4.将vdom渲染成真实dom
//5.数据更改了,data.name = '骏哥' 又生成虚拟dom(vdom)结构 
	//在这之中 //使用diff算法用来做比对两次vdom
		//diff算法是比较两个文件的差异,并将两个文件的不同之处,将这个不同之处生成一个补丁对象(patch.js)
		//diff算法来源后端
			//前端将其应用于虚拟dom的diff算法
			//vue中将虚拟dom的diff算法放在了patch.js
			//使用js来进行两个对象的比较(vdom 对象模型)
			//diff算法是同级比较
				//给每一个层级打一个标记,这个标记是一个数字(这个数字就是key)
//6.再通过render函数渲染成真实dom


### 关于diff算法返回的key


<div id='box'>
	<ul>
		<li v-for = '(item,index) in list' :key = 'item.id'>
			<p>{{item.text}}</p>
			<div>
				<button @click = 'changeStyle'>修改</button>
				<button @click = 'remove(index)'>删除</button>
			</div>
		</li>
	</ul>
</div>

<script>
	//id为
	new Vue({
		el:'#app',
		data:{
			list:[{
				id:1,
				text:'敲代码1'
			},
			{
				id:2,
				text:'敲代码2'
			}
			]
		},
		methods:{
			changeStyle(e){
				//接下来写的是为了给大家看key的作用,这段代码不要出现
				e.target.parentNode.parentNode.style.background = 'red'
				//删除以后会有上一层的样式
			},
			remove(index){
				this.list.splice(index,1)
			}
		}
	})
</script>




总结: 虚拟dom的执行步骤

​			1.获取数据

​			2.创建虚拟dom(这一步创建的是jsx语法糖,什么是虚拟dom?就是一个对象,里面模拟了真实dom的数据结构)

​			3.通过render函数解析jsx(js+xml的语法糖),将其转化成虚拟dom结构,再将虚拟dom渲染成真实的dom

​			4.当数据更改之后又会生成一次虚拟dom结构,这是时候就需要diff算法对比两次虚拟dom,**不同之处**会生成一个patch对象,(由于diff算法进行的是同级比较,而且会返回一个key值)再根据这个key值将patch对象渲染到页面中改变的结构上。(其他没有改变的地方是不做修改的,这就是虚拟dom的惰性原则)



posted @ 2019-06-24 10:48  mckk  阅读(1309)  评论(0编辑  收藏  举报