最近在審核新人代碼的時候,看到新人在vue中使用了document.getElementsByClassName
批注了盡量不操作原生dom建瘫,想附上原因甘穿,( ̄▽ ̄)" 發(fā)覺已然忘了為何不用,于是乎埋嵌,復習一回第献。
主要從查和增刪改兩個角度來分析虛擬dom的優(yōu)點贡必。
一、查
區(qū)別:
真實DOM操作:
document.get...
查詢的是整個節(jié)點樹庸毫。
ParentNode.querySelector()
和ParentNode.querySelectorAll()
是有范圍地查詢ParentNode下的節(jié)點仔拟,過程中是需要根據傳入的參數來比對節(jié)點上的屬性。
虛擬DOM操作:this.$refs.refName
查詢的是當前組件實例上的屬性$refs
對象中key為refName的屬性飒赃。
觀察一下當前組件實例:console.log(this)
課外復習:
參考:Document - Web API 接口參考 | MDN
真實DOM查詢節(jié)點的幾種方法:
getElementById()
getElementsByClassName()
getElementsByName()
getElementsByTagName()
getElementsByTagNameNS()
document.querySelector()
ParentNode.querySelector()
document.querySelectorAll()
ParentNode.querySelectorAll()
參考:ref - API — Vue.js
虛擬DOM查詢節(jié)點的方法:this.$refs.refName
二理逊、增刪改
普通的真實dom作增刪改時會引起瀏覽器的重排和重繪。
old:在虛擬dom出現(xiàn)之前比較好的操作是在文檔片段createDocumentFragment
或者拷貝節(jié)點cloneNode
中一次性把需要的增刪改都做好盒揉,再把這個片段或節(jié)點放到頁面中晋被。
// 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:現(xiàn)在幾大主流框架都實現(xiàn)了虛擬dom羡洛,并且實現(xiàn)了新舊節(jié)點比較,這就解決了以前多次重排重繪的問題藕漱,且減少了代碼量欲侮。
區(qū)別:
真實DOM操作:真實DOM增刪改 + (可能較多節(jié)點)重排與重繪
虛擬DOM操作:虛擬DOM增刪改 + 真實DOM差異增刪改(這與Diff算法效率有關) + (較少節(jié)點)重排與重繪