Vue dumb learning principle: real DOM into virtual DOM

Why use virtual DOM?

  • Operating the DOM in js is a very performance-consuming thing
  • May cause reflow and redraw
  • When the data changes, the virtual DOM only operates on the page once
  • Virtual DOM is used to improve performance

What is virtual DOM?

  • The virtual DOM can be understood as an HTML tag expressed in a string
  • Of course, this string is stored in the object data type
<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>

Take a look at the virtual DOM in Vue
Insert picture description here

Virtual DOM is a tree data structure

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

Insert picture description here

How did the real DOM come from

The template always exists in the memory, because this template is the basis of rendering.
As long as the corresponding interpolation syntax in the template is replaced with data, it can be rendered on the page. The
combination of the two is the real DOM.
Insert picture description here

Conversion between virtual DOM and real DOM

  • Actually it's almost the same as deep copy
  • Deeply traverse the real DOM, and convert to virtual DOM when encountering a node
  • Traverse the tags, just copy

Convert this set of tags into virtual 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>

Create a class

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)
	}
}
  • The beginning of the underscore represents private, readable and writable
  • The dollar sign starts with read-only
  • Use recursion to traverse DOM elements and generate virtual DOM
  • The stack structure used by the source code in Vue uses the stack to store parent elements to achieve recursive generation
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
}

Guess you like

Origin blog.csdn.net/m0_47883103/article/details/108640156