Eine winzige (512 Byte) virtuelle Dom -Template -Engine für eingebettete Projekte
| Dh / rande | Firefox | Chrom | Safari | Oper | iOS safari | Chrom für Android |
|---|---|---|---|---|---|---|
| Rand 14+ | 45+ | 49+ | 10+ | 37+ | 10.2+ | 55+ |
.Dom leiht einige Konzepte von React.js (z.
Warum? Denn mit einer solchen Bibliothek können Sie leistungsstarke GUIs in engen Raumumgebungen erstellen, wie z.
Tiny by Design : Die Bibliothek sollte die Größe von 512 Bytes niemals überschreiten. Das Ziel ist es nicht, eine weitere Template -Engine zu haben, sondern in 512 Bytes so viele Funktionen wie möglich zu haben. Wenn ein neues Merkmal benötigt wird, muss ein anderer Sakraktion oder der Umfang reduziert werden.
Für die Zukunft gebaut : Die Bibliothek nutzt die ES6 -Spezifikationen stark aus, was bedeutet, dass sie nicht von älteren Browsern unterstützt wird. Derzeit wird es von den 90% der Browser auf dem Markt unterstützt, erwartet jedoch, dass dies im nächsten Jahr nahezu 100% liegt.
Deklarativ : Beschreiben Sie Ihre HTML -DOM auf strukturierte, natürliche Weise und helfen Ihnen, leistungsstarke, aber lesbare Benutzeroberflächen zu erstellen.
Komponentenorientiert : Genau wie React.js fördert .
"Write Less" Accelerators : Die Bibliotheks -API ist speziell so konzipiert, dass sie über kurze Funktionsnamen und Beschleuniger verfügen, sodass Sie Ihre Ansichten mit weniger Code beschreiben können.
.dom Verwenden Sie .dom in Ihrem Projekt? Geben Sie dieses Repository auf und fügen Sie Ihre auf die Liste hinzu!
Für den minimalen Fußabdruck integrieren Sie dotdom.min.js.gz (512b) in Ihr Projekt.
< script src =" dotdom.min.js.gz " />Alternativ können Sie einfach die Minimified der Bibliothek direkt vor Ihrem Skript einfügen. Kopieren Sie einfach den Minimified Code.
Wenn Sie React.js bereits kennen, können die folgenden Beispiele Ihnen helfen, zu verstehen, wie sich die Primitiven der .dom -Primitive mit React beziehen.
Eine sehr einfache Dom -Struktur machen.
| Reagieren | .Dom |
|---|---|
ReactDOM . render (
React . createElement ( 'div' , null , 'Hello world' ) ,
document . body
) ; | R (
H ( 'div' , 'Hello world' ) ,
document . body
) |
Erstellen einer Komponente, auf der Sie Eigenschaften übergeben können.
| Reagieren | .Dom |
|---|---|
function Hello ( props ) {
return React . createElement (
'div' , null , `Hello ${ props . toWhat } `
) ;
}
ReactDOM . render (
React . createElement (
Hello , { toWhat : 'World' } , null
) ,
document . body
) ; | function Hello ( props ) {
return H ( 'div' , `Hello ${ props . toWhat } ` ) ;
}
R (
H ( Hello , { toWhat : 'World' } ) ,
document . body
) |
Erstellen von Komponenten, die ihren eigenen Zustand pflegen können.
| Reagieren | .Dom |
|---|---|
class Clickable extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
clicks : 0
} ;
}
render ( ) {
const { clicks } = this . state ;
return React . createElement (
'button' , {
onClick ( ) {
this . setState ( { clicks : clicks + 1 } )
}
} , `Clicked ${ clicks } times`
) ;
}
}
ReactDOM . render (
React . createElement ( 'div' , null ,
React . createElement ( Clickable , null , null ) ,
React . createElement ( Clickable , null , null )
) ,
document . body
) ; | function Clickable ( props , state , setState ) {
const { clicks = 0 } = state ;
return H ( 'button' ,
{
onclick ( ) {
setState ( { clicks : clicks + 1 } )
}
} ,
`Clicked ${ clicks } times`
) ;
}
R (
H ( 'div' ,
H ( Clickable ) ,
H ( Clickable )
) ,
document . body
) |
Die Komponente kann auch Lebenszyklusereignisse abonnieren:
| Reagieren | .Dom |
|---|---|
class WithLifeCycle extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
mounted : "no"
} ;
}
componentDidMount ( ) {
this . setState ( { mounted : "yes" } )
}
render ( ) {
const { mounted } = this . state ;
return React . createElement (
'div' , null , `mounted = ${ mounted } `
) ;
}
}
ReactDOM . render (
React . createElement ( 'div' , null ,
React . createElement ( WithLifeCycle , null , null ) ,
) ,
document . body
) ; | function WithLifeCycle ( props , state , setState , hooks ) {
const { mounted = "no" } = state ;
hooks . m . push ( ( ) => {
setState ( { mounted : "yes" } )
} ) ;
return H ( 'div' ,
`mounted = ${ mounted } `
) ;
}
R (
H ( 'div' , H ( WithLifeCycle ) ) ,
document . body
) |
KEYED -Updates ist eine nützliche Versöhnungsfunktion von React, mit der die Rendering -Engine intelligente Entscheidungen darüber treffen kann, welche Elemente aktualisiert werden.
Ein besonders nützlicher Fall ist, wenn Sie eine dynamische Liste von Elementen machen. Da die Rendering-Engine nicht versteht, welches Element sich geändert hat, endet er mit falschen Updates.
Um dieses Problem zu lösen, verwenden die VDOM -Motoren eine key , die ein Element im Baum eindeutig identifiziert. Domd löst es jedoch, indem es eine Kopie des Elementstatus in der Instanz des VDOM -Elements selbst aufbewahrt.
Dies bedeutet, dass Sie keine key Eigenschaft benötigen. Stellen Sie einfach sicher, dass Sie dieselbe VDOM -Instanz wie zuvor zurückgeben.
Wenn Sie dynamische Elemente erstellen (z. B. ein Array von VDOM -Elementen), kann .D .
| Reagieren | .Dom |
|---|---|
class Clickable extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
clicks : 0
} ;
}
render ( ) {
const { clicks } = this . state ;
const { ket } = this . props ;
return React . createElement (
'button' , {
onClick ( ) {
this . setState ( { clicks : clicks + 1 } )
}
} , `clicks= ${ clicks } , key= ${ key } `
) ;
}
}
const list = [ "first" , "second" , "third" ] ;
const components = list . map ( key =>
React . createElement ( Clickable , { key } , null ) ;
ReactDOM . render (
React . createElement ( 'div' , null ,
components
) ,
document . body
) ; | function Clickable ( props , state , setState ) {
const { clicks = 0 } = state ;
const { key } = props ;
return H ( 'button' ,
{
onclick ( ) {
setState ( { clicks : clicks + 1 } )
}
} ,
`clicks= ${ clicks } , key= ${ key } `
) ;
}
const list = [ "first" , "second" , "third" ] ;
const components = list . map ( key =>
H ( Clickable , { key } ) ;
R (
H ( 'div' , components ) ,
document . body
) |
Beachten Sie, dass die obige Lösung die staatlichen Komponenten korrekt aktualisiert, auch wenn sich ihre Bestellung geändert hat. Wenn Sie jedoch die vollständige, reag-ähnliche Funktionalität wünschen, die einzelne Schlüssel aktualisiert, können Sie das Keyed Plug-In verwenden.
function Container ( props , state ) {
const { components } = props ;
// The function `K` accepts the component state and an array of components that
// contain the `key` property, and returns the same array of components, with their
// state correctly manipulated.
return H ( "div" , K ( state , components ) ) ;
} Sie können rohe (unversöhnliche) vdom -Knoten (z. B. einen willkürlichen HTML -Inhalt) erstellen, indem Sie die .r -Eigenschaft des Hooks -Objekts auf jeden Wahrheitswert festlegen.
Dies deaktiviert die weitere Versöhnung mit den Kinderknoten und hält daher Ihre Inhalte intakt.
function Description ( props , state , setState , hooks ) {
const { html } = props ;
hooks . r = 1 ; // Enable raw mode
return H ( 'div' , {
innerHTML : html
} )
} R( VNode, DOMElement ) R ( H ( 'div' , 'Hello' ) , document . body )Rendert den angegebenen Vnode -Baum zum angegebenen DOM -Element. Weitere Aktualisierungen von staatlichen Komponenten werden nur bei ihren unmittelbaren Kindern stattfinden.
H( tagName | function, [properties], [children ...]) H ( 'tag' )
H ( 'tag' , { prop : "value" } )
H ( 'tag' , H ( 'child' ) )
H ( 'tag' , { prop : "value" } , H ( 'child' ) )
H ( Component , { prop : "value" } )Erstellt ein Vnode -Element. Wenn eine Zeichenfolge als erstes Argument übergeben wird, wird ein HTML -Element erstellt. Wenn eine Funktion gegeben wird, wird eine staatliche Komponente erstellt.
Eigenschaften und Kinder sind optional und können weggelassen werden.
Anstelle eines Tag-Namens können Sie eine Funktion angeben, die ein virtuelles DOM gemäß einer höheren Logik zurückgibt. Eine solche Funktion hat die folgende Signatur:
const Component = ( props , state , setState , hooks ) {
// Return your Virtual DOM
return div ( ... )
} Die Eigenschaften props enthält das Eigenschaftenobjekt wie bei erstellten Komponente angegeben.
Der state wird in ein leeres Objekt {} initialisiert und wird aktualisiert, indem die Methode setState({ newState }) aufgerufen wird. Letzteres wird auch ein Update für die Komponente und ihre Kinder auslösen.
Sie können dem state auch direkt Eigenschaften zuweisen, wenn Sie kein Update verursachen möchten.
Das hooks -Objekt kann verwendet werden, wenn Sie Handler an den Komponenten-Lebenszyklus-Methoden registrieren möchten.
Ähnlich wie bei React haben die .Dom -Komponenten einen Lebenszyklus:
Um auf die Lebenszyklusmethoden zuzugreifen, müssen Sie das vierte Argument für Ihre Komponentenfunktion verwenden. Insbesondere müssen Sie Ihre Handhabungsfunktion in einem der folgenden Felder drücken:
const Component = ( props , state , setState , hooks ) {
hooks . m . push ( ( domElement ) => {
// '.m' is called when the component is mounted
} ) ;
hooks . u . push ( ( ) => {
// `.u` is called when the component is unmounted
} ) ;
hooks . d . push ( ( domElement , previousDomElement ) => {
// `.d` is called when the component is updated
} ) ;
...
}tag( [properties], [children ...] ) const { div , span , a } = H ;
div ( 'hello' , span ( 'world' ) )
div ( 'click' , a ( { href : '#' } , 'Here' ) , 'to continue' ) Eine Abkürzungsfunktion kann als Eigenschaft aus der H -Funktion extrahiert werden. Solche Kurzstufen verhalten sich genau wie H , aber mit dem bereits besiedelten Tag -Namen.
Es wird empfohlen, zu Beginn Ihres Skripts eine Dekonstruktionsaufgabe zu verwenden, um JavaScript -Minifikatoren zu helfen, das Ergebnis weiter zu optimieren:
const {div, span, a, button} = H;
tag.class( [properties], [children ...] ) const { h1 , span , p } = H ;
h1 . short ( 'short header' , span . strong ( 'strong text' ) )
button . primary ( { onclick : handleClick } , 'Primary Action' )
p . bold . italic ( twitterPost ) Anstatt den className als Eigenschaft anzugeben, können Sie den .className -ShortHand in Kombination mit den Kurzfilmmethoden verwenden.
Dies ist das gleiche wie das Aufrufen von div({className: 'className'}) und die Funktionsinterface ist genau das gleiche wie oben.
Hinweis: Sie können mehr als eine Klasse hinzufügen, indem Sie mehr als eine .class zum Tag verkettet. Zum Beispiel: div.foo.bar ist der gleiche wie div({className: 'foo bar'}) .
Da der Fokus des Projekts die geringe Größe aufweist, fehlen die Überprüfungen der Vernunft. Dies macht es anfällig für Fehler. Seien Sie sehr vorsichtig mit den folgenden Einschränkungen:
Sie können kein Update mit einer Eigenschaft entfernt werden. Sie müssen die neue Eigenschaft stattdessen auf einen leeren Wert setzen. Zum Beispiel:
// Wrong
R ( div ( { className : 'foo' } ) , document . body ) ;
R ( div ( { } ) , document . body ) ;
// Correct
R ( div ( { className : 'foo' } ) , document . body ) ;
R ( div ( { className : '' } ) , document . body ) ; Sie dürfen niemals eine Eigenschaft mit dem Namen $ in Ihren Komponenten verwenden. Wenn Sie dies tun, wird das Eigenschaftsobjekt als virtueller DOM -Knoten angesehen und führt zu unerwarteten Ergebnissen.
// *NEVER* do this!
R ( H ( MyComponent , { $ : 'Foo' } ) , document . body ) K(state, components)In
plugin-keyed.min.js
Stellt sicher, dass der Zustand der Komponenten in der Liste gemäß ihrer key synchronisiert ist. Auf diese Weise können Sie wie SO reag-ähnliche key-teured-Updates durchführen:
function ValueRenderer ( ... ) {
...
}
function MyComponent ( props , state ) {
const { values } = props ;
const components = values . map ( value => {
H ( ValueRenderer , {
key : value ,
value : value
} ) ;
} )
// Synchronize state of components, based on their key
return H ( 'div' , K ( state , components ) )
} Möchten Sie zu .dom beitragen? Sie sind mehr als willkommen! Befolgen Sie einfach die Richtlinien:
npm install
npm test && npm run build && ls -l dotdom.min.js.gz
Wenn Tests bestehen und die Größe von dotdom.min.js.gz kleiner oder gleich 512 Bytes ist, erstellen Sie eine Pull -Anforderung. Andernfalls reduzieren Sie Ihren Umfang oder denken Sie an eine andere Implementierung, um sie wieder auf 512 Bytes zu bringen.
Stellen Sie sicher, dass Sie Ihren Code ordnungsgemäß kommentieren, da Sie höchstwahrscheinlich extreme JavaScript -Hacking durchführen müssen. Die Gudeliens sind die folgenden:
/**
* Functions are commented as JSDoc blocks
*
* @param {VNode|Array<VNode>} vnodes - The node on an array of nodes to render
* ...
*/
global . R = render = (
vnodes , // Flat-code comments start on column 70 and
dom , // wrap after column 120.
/* Logical separations can be commented like this */
...Lizenziert unter der Apache -Lizenz, Version 2.0