tools to work with a virtual dom
React is probably the first to have done this and gain massive hype with it. However it grew extremely large, being >500k unminified.
mithril.js also has a virtual dom and claims to do dom diffing. However, it is a complete MVC framework, complete with its own promises implementation, xhr, etc. But at least it is very small, although not very readable.
virtual-dom/
mercury seems like a very good
solution. It has a lot more flexibility and deals with properties
instead of
with attributes
by default.
And of course, I don’t want to merely use a library. I want to know and understand the technology, so I might as well implement it myself :-)
$ component install Swatinem/virtualdom
Creates a virtual dom node for the real DOM node
.
Creates a real DOM node for the virtual dom vnode
.
Creates a list of patches to transform from
to to
.
Applies a list of patches, see below for patch details.
A text node is simply a js string.
A comment node is {comment: 'comment content'}
And a normal node is represented as:
{
key: 'optional internal identifier used for sorting',
tag: 'div',
ns: 'optional namespace, like "http://www.w3.org/2000/svg" for svg'
class: ['array', 'of', 'classes'],
style: {position: 'absolute', borderRadius: '5px'},
data: {dataset: 'key value pairs'},
attributes: {'id': 'id', 'value': 'key value pairs for attributes'},
children: [array, of, children, or, a, single, child]
}
class
, data
and style
are handled separately from other attributes
since they have array or hashtable-like accessors in the real DOM.
{
node: [], // chain of `childNodes` positions, starting at the room node
// and patches, which are all optional:
addClasses: [],
removeClasses: [],
setStyles: {},
removeStyles: [],
setAttributes: {},
removeAttributes: [],
setData: {},
removeData: [],
setContent: '', // for text and comment nodes
childPatches: [/* see below */]
}
// and childPatches:
{
type: 'insert',
child: newChild,
index: 0, // required, will insert at the specified index
}
{
type: 'replace',
child: newChild,
index: 0, // required, index of the old child
}
{
type: 'remove'
index: 0
}
// might be good to have, but very difficult to implement as a diff
{
type: 'move'
from: 0, // old index
to: 1 // new index
}
- reorder / move child nodes
- support innerHTML for unsafe code
LGPLv3
Released as free software as part of ChatGrape