Vue笨蛋学原理:真实DOM转换为虚拟DOM

为什么要使用虚拟DOM?

  • 在js中操作DOM是一件很消耗性能的事
  • 可能会造成回流和重绘
  • 数据改变的时候虚拟DOM只对页面进行一次操作
  • 使用虚拟DOM是为了提高性能

什么是虚拟DOM?

  • 可以把虚拟DOM理解为一个用字符串表达的HTML标签
  • 当然了,这个字符串是存放在对象数据类型里的
<div/>  => {tag:'div'}

<div>我是内容</div> => {tag:'div',value:'我是内容'}

<div title="1" class="c"> => {tag:'div',data:{title:'1',class:'c'}}

<div>   => {tag:'div',children:[{tag:'div'}]}
  <div><div>
</div>

看一下Vue里的虚拟DOM
在这里插入图片描述

虚拟DOM是树数据结构

<div id="root"> 
	<div>
		<p>{{name}}-{{message}}</p>
	</div>
	<p>{{name}}</p>
	<p>{{message}}</p>
</div>

在这里插入图片描述

真实DOM怎么来的

模板一直存在在内存里,因为这个模板是渲染的根本
只要模板里对应的插值语法替换为数据就可以渲染到页面上了
他俩结合就是真实的DOM
在这里插入图片描述

虚拟DOM和真实DOM的转换

  • 其实和深拷贝差不多
  • 深度遍历真实DOM,遇到节点就转换为虚拟DOM
  • 遍历标签,复制而已

把这一组标签转换为虚拟DOM

<div id="root"> 
	<div>
		<div>hello1</div>
		<div>hello2</div>
		<div>hello3</div>
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
		</ul>
	</div>
</div>

创建一个类

class Vnode{
	constructor((tag,data,value,type)) {
	    this.tag = tag.toLowerCase(); // 标签名
			this.data = data;  // 值
			this.value = value; // 文本
			this.type = type;  // 元素类型
			this.children = []  // 子节点
	}
	
	// 如果有追加节点,就用这个方法
	appendChild(vnode) {
		this.children.push(vnode)
	}
}
  • 下划线开头代表私有的,可读可写
  • 美元符号开头代表只读
  • 使用递归来遍历DOM元素,生成虚拟DOM
  • Vue中的源码使用的栈结构,使用栈存储父元素来实现递归生成
function getVNode(node) {  // 参数为真正的DOM
	let nodeType = node.nodeType;
	let _vnode = null;
	// 对节点进行判断
	if(nodeType === 1) { // 元素节点
		let nodeName = noew.nodeName
		let attrs = node.attributes  // 属性,返回属性组成的为数组,我们就是把这个伪数组转换为对象
		let _arrtObj = {}
		
		// 循环 attrs
		for(let i = 0; i < attrs.length; i++) {
			// attrs[i]是一个属性节点,我们要的是nodeName这个属性
			_arrtObj[attrs[i].nodeNarme] = attrs[i].nodeValue
		}
		_vnode = new Vnode(nodeName,_attrObj,undefined,nodeType)
		
		let childNodes = npde.childNodes;
		for(let i = 0; i < childNodes.length; i++) {
			_vnode.appendChild(getVNode(childNodes[i])) // 递归
		}
	} else if (nodeType === 3) {
		_Vnode = new Vnode(undefined,undefined,node.nodeValue,nodeType)
	}
	
	return _vnode
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值