render(element, vnodes)
描述
將模板渲染至 DOM。
m.render(document.body, 'hello');
// <body>hello</body>
簽名
m.render(element, vnodes, redraw)
引數 | 類型 | 是否必填 | 描述 |
---|---|---|---|
element | Element | 是 | 作為子樹父節點的 DOM 元素。 |
vnodes | Array<Vnode>|Vnode | 是 | 待渲染的 vnodes。 |
redraw | () -> any | 否 | 每次呼叫子樹中的事件處理函式時都會呼叫的回調函式。 |
返回值 | 傳回 undefined 。 |
運作方式
m.render(element, vnodes)
方法接受一個虛擬 DOM 樹(通常透過 m()
hyperscript 函式 產生),產生一個 DOM 樹並將其載入至 element
上。如果 element
已經透過先前的 m.render()
呼叫載入了一個 DOM 樹,則 vnodes
會與先前的 vnodes
樹進行比對,並且僅在需要反映變更時才修改現有的 DOM 樹。未變更的 DOM 節點將不會被更動。
如果您傳遞可選的 redraw
參數,則每次呼叫子樹中任何位置的事件處理函式時,都會呼叫該參數所指的函式。這被 m.mount
和 m.redraw
用於實現 自動重繪 功能,同時也開放出來用於更進階的使用情境,例如與某些第三方框架整合。
m.render
是同步的。
為什麼使用虛擬 DOM
在每次重繪時產生一個 vnode 樹似乎是浪費的,但事實證明,與讀取和修改 DOM 相比,建立和比較 JavaScript 資料結構出乎意料地更有效率。
由於一些原因,操作 DOM 可能非常耗費資源。交替讀取和寫入可能會因為導致瀏覽器頻繁重繪而對效能產生負面影響,而比較虛擬 DOM 樹則允許將寫入操作批次處理至單次重繪中。此外,各種 DOM 操作的效能特性在不同實作之間有所差異,並且可能難以學習和針對所有瀏覽器進行最佳化。例如,在某些實現中,讀取 childNodes.length
的複雜度為 O(n);在某些實現中,讀取 parentNode
會導致重繪,等等。
相比之下,遍歷 JavaScript 資料結構具有更可預測和穩定的效能表現,此外,vnode 樹的實現方式使得現代 JavaScript 引擎能夠應用積極的最佳化,例如隱藏類,以獲得更好的效能。
與其他 API 方法的差異
m.render()
方法在內部被 m.mount()
、m.route()
、m.redraw()
和 m.request()
呼叫。它不會在 串流更新 後被呼叫。
與 m.mount()
和 m.route()
不同,透過 m.render()
渲染的 vnode 樹不會自動重繪以響應視圖事件、m.redraw()
呼叫或 m.request()
呼叫。它是一種底層機制,適用於希望手動控制渲染而非依賴 Mithril.js 內建自動重繪系統的程式庫開發者。
另一個差異是 m.render
方法期望一個 vnode(或一個 vnodes 陣列)作為其第二個參數,而 m.mount()
和 m.route()
期望元件。
獨立使用
var render = require("mithril/render")
m.render
模組在功能上與 Knockout、React 和 Vue 等視圖庫相似。它實現了一個虛擬 DOM 比對引擎,具有現代搜尋空間縮減演算法和 DOM 回收,這轉化為頂尖的效能,無論是在初始頁面載入還是重新渲染方面。除了透過 require("mithril/render/vnode")
暴露的標準化之外,它不依賴 Mithril.js 的其他部分,並且可以用作獨立運作的程式庫。
儘管相對較小,但 render 模組功能齊全且獨立運作。它支援您可能期望的一切:SVG、自訂元素以及所有有效的屬性和事件 - 沒有任何奇怪的區分大小寫的邊緣情況或例外。當然,它也完全支援 元件 和 生命週期方法。
當使用 m.render
作為獨立模組時,導入 hyperscript 函式
以建立要渲染的 vnodes 可能會很有幫助。