使用虚拟dom和真实dom的区别

最近在审核新人代码的时候,看到新人在vue中使用了document.getElementsByClassName
批注了尽量不操作原生dom,想附上原因,( ̄▽ ̄)" 发觉已然忘了为何不用,于是乎,复习一回。


主要从查和增删改两个角度来分析虚拟dom的优点。

一、查

区别:
真实DOM操作:
document.get...查询的是整个节点树。
ParentNode.querySelector()ParentNode.querySelectorAll()是有范围地查询ParentNode下的节点,过程中是需要根据传入的参数来比对节点上的属性。
虚拟DOM操作:this.$refs.refName查询的是当前组件实例上的属性$refs对象中key为refName的属性。
观察一下当前组件实例:console.log(this)

课外复习:
参考:Document - Web API 接口参考 | MDN
真实DOM查询节点的几种方法:

  1. getElementById()
  2. getElementsByClassName()
  3. getElementsByName()
  4. getElementsByTagName()
  5. getElementsByTagNameNS()
  6. document.querySelector()
  7. ParentNode.querySelector()
  8. document.querySelectorAll()
  9. ParentNode.querySelectorAll()

参考:ref - API — Vue.js
虚拟DOM查询节点的方法:this.$refs.refName

二、增删改

普通的真实dom作增删改时会引起浏览器的重排和重绘。
old:在虚拟dom出现之前比较好的操作是在文档片段createDocumentFragment或者拷贝节点cloneNode中一次性把需要的增删改都做好,再把这个片段或节点放到页面中。

// bad
let ul = document.querySelector('#mylist');
ul.append(li)
ul.append(li)
ul.append(li)

// good,两次重排重绘
let ul = document.querySelector('#mylist');
ul.style.display = 'none'; // 减少重绘
ul.append(li)
ul.append(li)
ul.append(li)

// better,一次重排重绘
let fragment = document.createDocumentFragment();
fragment .append(li)
fragment .append(li)
fragment .append(li)
ul.appendChild(fragment);

new:现在几大主流框架都实现了虚拟dom,并且实现了新旧节点比较,这就解决了以前多次重排重绘的问题,且减少了代码量
区别:
真实DOM操作:真实DOM增删改 + (可能较多节点)重排与重绘
虚拟DOM操作:虚拟DOM增删改 + 真实DOM差异增删改(这与Diff算法效率有关) + (较少节点)重排与重绘

你可能感兴趣的:(使用虚拟dom和真实dom的区别)