Erstellen Sie UI -Komponenten mit dem HTML, den Sie bereits haben.
2 KB GZIPPED und 6 KB Minified! ?
data in Ihr vorhandenes HTML fallen < div data-component =" Counter " >
< p data-bind =" state:Counter.count " > 0 </ p >
< button data-action =" click->Counter.decrement " >
-1
</ button >
< button data-action =" click->Counter.increment " >
+1
</ button >
</ div >class ? import { Component } from "domponent" ;
export default class Counter extends Component {
constructor ( el ) {
super ( el ) ;
}
increment ( ) {
this . setState ( { count : this . state . count + 1 } ) ;
}
decrement ( ) {
this . setState ( { count : this . state . count - 1 } ) ;
}
} import { Init } from "domponent" ;
import Counter from "./Counter.js" ;
const config = {
selector : document . getElementById ( "root" ) ,
components : {
Counter
} ,
appCreated : callbackFunction
} ;
new Init ( config ) ;Und du bist gut zu gehen !!
Diese Bibliothek stellt eine saubere und moderne Möglichkeit ein, HTML in UI -Komponenten zu verwandeln. Sie können einfach einige Datenbindungen implementieren, Umfang verarbeiten, Daten umgeben und Komponenten erstellen, indem Sie einige der Konventionen in diesem Skript verwenden. Es soll eine sehr sehr leichte Alternative zu Stimulusjs mit einem kleinen Reaktionsgeschmack (Lebenszyklusmethoden, Requisiten und Komponentenzustand) sein.
Domponent verarbeitet das clientseitige Rendering nicht aus dem Box, erstellt kein virtuelles DOM und differentiert keine DOM (obwohl es Differenzstaat und Requisiten durchführen). Es ist nicht dazu gedacht, Routing oder gesamten Anwendungszustand zu bewältigen. Es soll HTML -Fragmente (Thymeleaf, Schienen, Mops, EINZIGEN TEMPLE -Engine, die Sie verwenden) aufnehmen und wiederverwendbare Funktionen in Form von Komponenten erstellen.
Domponent ähnelt in gewisser Weise dem Knockout:
Im Gegensatz zu Knockoutjs, Domponent:
Ausschlagen
Html
< p > First name: < input data-bind =" value: firstName " /> </ p >
< p > Last name: < input data-bind =" value: lastName " /> </ p >
< h2 > Hello, < span data-bind =" text: fullName " > </ span > ! </ h2 >JS
var ViewModel = function ( first , last ) {
this . firstName = ko . observable ( first ) ;
this . lastName = ko . observable ( last ) ;
this . fullName = ko . pureComputed ( function ( ) {
return ` ${ this . firstName ( ) } ${ this . lastName ( ) } ` ;
} , this ) ;
} ;
ko . applyBindings ( new ViewModel ( "Planet" , "Earth" ) ) ;Domponent
Html
< div data-component =" Hello " data-state =" { " firstName ": "Planet", "lastName": "Earth"}" >
< p > First name: < input data-action =" input->Hello.setFirstName " /> </ p >
< p > Last name: < input data-action =" input->Hello.setLastName " /> </ p >
< h2 > Hello, < span data-bind =" state:Hello.fullName " > </ span > ! </ h2 >
</ div >JS
import { Component } from "domponent" ;
export default class Hello extends Component {
constructor ( conf ) {
super ( conf ) ;
}
setFirstName ( event ) {
this . setState ( { firstName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setLastName ( event ) {
this . setState ( { lastName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setFullName ( ) {
this . setState ( {
fullName : ` ${ this . state . firstName } ${ this . state . lastName } `
} ) ;
}
}https://tamb.github.io/domponent/
TODO LISTE: https://codesandbox.io/embed/domponent-todo-with-undo-redo-sp3s2?fontsize=14
Lokale Demo
git clone dieses Reponpm installnpm run build:html-dev oder npm run build:html-prod npm install -- save domponent Sie können eine ES5 -Version verwenden, indem Sie diese Datei domponent/dist/domponent.es5.production.min.js importieren
Wenn Sie keinen Transpiler verwenden, wird empfohlen, die ES5 UMD zu verwenden. Hier ist der JSDelvr -Link:
// production
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.production.min.js" defer > </ script >
// development
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.development.min.js" defer > < / script > Hinweis: Verwenden Sie so viel oder so wenig von dieser Bibliothek, wie Sie möchten. Sie können dies nur für data-component , data-ref und data-ref-array Attribute verwenden und Ihre DOM-Auswahl erheblich erleichtern. Mit der Exponent -Klasse können Sie staatenlose Komponenten erstellen. Der Himmel ist die Grenze. Domponent ist im Kern eine Reihe von Versorgungsklassen für Ihre HTML.
data-component Wir verwenden diesen bösen Jungen, um den Komponentennamen mit seiner entsprechenden class im Init -Konfigurationsobjekt abzustimmen
Beispiel: Wenn Ihr HTML data-component="Counter" ist | Sie müssen über eine Komponente in Ihrer Konfiguration bezeichnet werden, die als Counter bezeichnet wird
data-bind Binds state or props to the textContent of an element First you specify if you want to bind state or props data-bind="state:Counter.count" or data-bind="props:Counter.count" The left half of the : tells the component what object to bind to (state or props), the right half tells the component what key within the state or props to read from
data-actionBindet ein DOM -Ereignis mit einer Komponentenmethode. Betrachten Sie Folgendes:
< button data-action =" click->Counter.increment " >
+1
</ button > Die linke Hälfte der : repräsentiert die wörtliche Zeichenfolge für das DOM -Ereignis, auf das man sich anhören kann. Die rechte Hälfte entspricht der Komponentenmethode
Hinweis: Sie können mehrere Hörer mit einer Pfeife hinzufügen | Beispiel:
< button data-action =" click->Counter.increment|mouseover->Counter.anotherMethod " >
+1
</ button > Sie können eventListener -Optionen auch eingeben. Optionen müssen nach a sein . Nach der Klassenmethode. Die Optionen müssen durch ein Komma getrennt werden ,
< button
data-action =" click->Counter.increment.passive,capture|mouseover->Counter.anotherMethod.once,passive "
>
+1
</ button > data-state Wenn Sie Ihre Komponente mit einem bestimmten Zustand im Speicher instanziieren möchten, müssen Sie ein data-state -Attribut an das Stammelement des Komponentenbeispiels anhängen:
<div data-component="Counter" data-state='{"count":24, "isEven": true}'>
...
</div>
Das stimmt. data-state nimmt ein gültiges JSON-Objekt ein.
data-ref Wenn Sie auf DOM-Elemente verweisen müssen, können Sie data-ref wie SO verwenden:
< div data-ref =" Counter.myElement " > </ div > Sie müssen vorab vornehmen, auf welcher Komponente das Element ist. Es wird dann in den Komponenten $refs -Objekt gespeichert.
Sie können dann mit diesem Counter auf das Element zugreifen this.$refs.myElement innerhalb der Komponenteninstanz.
data-ref-arrayAuf diese Weise können Sie eine Reihe von Elementen in Ihrer Komponente erstellen:
< div data-ref-array =" Counter.elements " > </ div >
< div data-ref-array =" Counter.elements " > </ div > Es wird dann in den Komponenten $refs -Objekt gespeichert. Sie können this.$refs.elements .
data-key Dies ist völlig optional. Es ist eine eindeutige Zeichenfolge für jede Komponenteninstanz.
Dies wird intern verwendet, um Requisiten zu binden. Daher müssen Sie den $key der Komponente kennen, von dem Sie Requisiten erhalten.
< div data-component =" Counter " data-key =" aUniqueKey " >
...
</ div >Nehmen wir an, Sie verfolgen dies in Ihrer Vorlagensprache. Sie sollten sicherstellen, dass Ihre Schlüssel einzigartig sind.
# for (let i=0; i < 10 ; i++){
< div data-component =" Counter " key =" `aUniqueKey${i}` " > ... </ div >
} Wenn Sie dieses Attribut nicht verwenden, wird jeder Komponenteninstanz automatisch ein eindeutiger Schlüssel zugewiesen. Es kann über this.$key
data-props Sie können den Zustand von einer übergeordneten Komponente als props in einer untergeordneten Komponente teilen. Das Markup würde so aussehen
< div data-component =" Counter " key =" parentCounter " >
< div
data-props =" myAwesomeProp<-parentCounter:ofFive "
data-component =" DisplayAnything "
> </ div >
</ div > Die linke Seite des Pfeils <- ist der Name der Requisiten in der DisplayAnything Komponente. Die rechte Seite des Pfeils ist $key der übergeordneten Komponente, ein : und der Name des state zu erben.
Sie können dann die Lifecycle -Methoden propsWillUpdate und propsDidUpdate verwenden, um Änderungen in Ihrer untergeordneten Komponente vorzunehmen.
Component ?Lassen Sie uns mit dem Schalter fortfahren. Die minimale JS, die zum Erstellen einer Komponente erforderlich ist, finden Sie unten:
class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
}
} super fügt die Basismethoden und Eigenschaften hinzu, die Ihre Komponente benötigt.
Mutiere den Zustand nicht direkt. Nennen Sie this.setState
setState ( stateObject , callbackFunction ) ;Dies ist im Konzept ähnlich wie Reacts SetState - obwohl es unterschiedlich implementiert ist.
Sie können Ihre JS -Komponente Standardzustände hinzufügen und sie im DOM überschreiben
export default class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
this . state = {
count : parseInt ( this . state . count ) || 0 ,
isEven : this . state . count
? this . state . count % 2 === 0
? true
: false
: true ,
stateFieldFromDOM : this . state . stateFieldFromDOM || "default cat" ,
stateFieldDefault : "default iPhone 11"
} ;
this . setState ( this . state ) ;
} <div data-component="Counter" data-state="{"count": 4, "isEven":true, "stateFieldFromDOM": "some value here"}"
Die obigen Zustandsfelder überschreiben die Standard -JS -Statusfelder.
Die Wertbindung von setState wird immer in textContent betragen. Wenn Sie Status/Requisiten verwenden möchten, um HTML zu rendern, können Sie einen Beobachter für diesen Wert hinzufügen und den $refs -Knoten aktualisieren, in dem das neue HTML untergebracht wird.
watch ( ) {
return {
count : {
post ( newCount ) {
this . $refs . exclaimCount . innerHTML = `<div class="uppercase"> ${ newcount } !</div>` ;
}
}
}
}Die folgenden Methoden, mit denen Sie an verschiedenen Stellen in ihrem Lebenszyklus auf Komponenten zugreifen können
| Lebenszyklusmethode | Kontext | Beschreibung |
|---|---|---|
| Verbinden | Komponente/Exponent | Bevor die Bibliothek eine Ihrer Komponenten/Exponenten erhöht und Sie Zugriff auf andere Methoden haben |
| verbunden | Komponente/Exponent | Nachdem Ihre Komponente/Ihr Exponent verkabelt wurde und alle EventListener vorhanden sind |
| Trennen | Komponente/Exponent | Vor dem Entfernen von EventListenern und Löschen von Komponenten/Exponenten aus dem Speicher |
| Propsillupdate | Komponente/Exponent | Bevor die Requisiten in Ihrer Komponente aktualisiert werden, sind keine DOM -Mutationen stattgefunden |
| PropsDidUpdate | Komponente/Exponent | Nachdem die Requisiten aktualisiert haben und sich das DOM verändert hat |
| landeswesen | Komponente | Vor dem Stand der aktuellen Komponente oder einer der Requisiten seiner Angehörigen haben sich geändert |
| STATEDIDUPDATE | Komponente | Kinderkomponenten mit ererbten Requisiten haben ihre DOM -Manipulationen und -zustände und Requisiten geändert |
Component und Exponent haben eine watch , die ein Objekt zurückgeben muss. Mit den Beobachtern können Sie sich während der Komponentenlebensdauer in einen bestimmten state oder props -Wertänderungen anschließen. Auf diese Weise kann Ihre Zustandslogik isoliert werden propsWillUpdate anstatt alles mit stateWillUpdate , stateDidUpdate oder propsDidUpdate zu klumpen. Dies soll die Beobachter in Vue.JS genau imitieren. HINWEIS : Nennen props Ihre state nicht gleich. Dies ist eine schlechte Übung und wird die Beobachter brechen.
watch ( ) {
return {
myField : {
pre ( newValue , oldValue ) {
// my logic
} ,
post ( newValue ) {
// my logic
}
}
}
} Sie können Ihre angesehenen Zustandsfelder in den Komponenten $watchers -Objekt anzeigen.
Erweitern Sie die Exponent , um eine Komponente mit nur props zu erstellen. Dies ist etwas leichter als eine Component . Schneller zu verdrahten und weniger Speicher aufzunehmen.
import { Exponent } from 'domponent'
class StatelessThing extends Exponent{
constructor(conf){
super(conf);
}
}
Sie haben dann nur Zugriff auf:
propsWillUpdatepropsDidUpdate Warum Exponent ?
Weil es einfach die angegebenen Daten interpretiert oder erklärt ... und es klingt nach Komponenten.
Komponenten oder Exponenten erhalten die folgenden Felder.
| Feldname | Typ | Zugang | Kontext | Beschreibung |
|---|---|---|---|---|
| $ App | Objekt | öffentlich | Komponente/Exponent | Die gesamte Domponent -Anwendung |
| $ b | Array | Privat | Komponente/Exponent | EventListener -Bindungen für den internen Gebrauch |
| $ d | Objekt | Privat | Komponente | Die übergeordneten Komponenten beziehen sich auf seine Kinder |
| $ key | Saite | öffentlich | Komponente/Exponent | Eindeutige Kennung für die Komponenteninstanz |
| $ Name | Saite | öffentlich | Komponente/Exponent | Der Name des Komponententyps |
| $ p | Objekt | Privat | Komponente/Exponent | Interne Sammlung von Requisiten und seine DOM -Referenzen |
| Requisiten | Objekt | öffentlich | Komponente/Exponent | Schlüssel-/Wert -Datenpaare übergeben |
| $ root | Element | öffentlich | Komponente/Exponent | Der Root -Dom -Knoten der Komponente |
| $ s | Objekt | Privat | Komponente | Interne staatliche Sammlung und seine DOM -Referenzen |
| Zustand | Objekt | öffentlich | Komponente | Tasten-/Wert -Datenpaare, die aktualisiert werden können |
| $ Beobachter | Objekt | öffentlich | Komponente | Speichernde Änderungsfunktionen und deren jeweilige Zustands- und Requisitenschlüssel |
Init -Funktion? Diese Funktion erstellt die App und registriert alle Komponenten. Dies erfordert ein config nach dem erforderlichen Argument:
const config = {
selector : document . getElementById ( "root" ) ,
components : { Counter } ,
appCreated : callbackFunction
} ;
const App = new Init ( config ) ;Anschließend enthält es die folgenden Methoden:
Und die folgenden Objekte:
Sie können das components der Konfiguration auch ausschließen und eine App erstellen, ohne dass Komponenten zu Beginn beginnen.
createComponent@params:
App . createComponent ( document . getElementById ( "added-html" ) , callback ) ; register@params
App . register ( NewComponent , callback ) ; deleteComponent@params:
data-key this.$key App . deleteComponent ( "my-component-instance-key" , callback ) ; unregister@params:
App . unregister ( "NewComponent" , callback ) ; Um data- zu vermeiden, die mit anderen Selektoren, Bibliotheken usw. zusammenhängen, können Sie die Standardattributnamen im App-Konfigurationsobjekt überschreiben:
Init ( {
selector : getElementById ( 'root),
components : { Counter } ,
dataAttributes : {
component : 'mynamespace-component' ,
state : 'cool-state' ,
}
} ) ;Dies bedeutet, dass Ihr HTML so aussieht:
< div data-mynamespace-component =" Counter " data-cool-state =' {"count":12} ' >
...
</ div >Sie können die Syntax, die Sie in Ihrem HTML verwenden, optional anpassen. Die folgenden Elemente können angepasst werden.
INHERITS_FROM: '<-',
FROM_COMPONENT: '.',
KEY_VALUE: ':',
MULTIPLE_VALUES: "|",
METHOD_CALL: "->",
LIST: ","
Dies bedeutet, dass Sie in Ihrer Konfiguration hinzufügen können:
{
customSyntax : {
LIST : "!" ,
METHOD_CALL : "#"
}
}Und Ihr HTML kann dies verwenden!
Bei der Entwicklung mit Domponent fügt die Verwendung des Entwicklungsbaus hilfreiche Fehler und Anmeldungen Ihrer Konsole von Development DOM hinzu (dieser Typ->)?
Der einfachste Weg, dies zu verwenden, ist mit Webpack -Aliase:
resolve : argv . mode === 'development' ? {
alias : {
domponent : 'domponent/dist/domponent.development.js'
}
} : { } ,Auf diese Weise wird Ihr Entwicklungsaufbau von WebPack die Produktionsversion von Domponent für die Version von DOM ausgetauscht.
Sie können Ihre Komponente HTML für verschiedene Vorlagenmotoren schreiben und sie als Teilungen/Fragmente/unabhängig von Ihrem Motor als "Teile von HTML" einfügen .
Hier sind einige Beispiele dafür, wie Sie Domponent verwenden könnten.
Hinweis: Denken Sie trotz dieser Syntaxunterschiede im Markup daran, dass die Komponente einfach eine JS -Klasse ist.
PUG -Syntax Beispiel ?
// counter.pug
mixin counter ( count )
div ( data - component = "Counter" data - state = `
{
"count": count,
"isEven": count % 2 === 0
}
` )
p ( data - bind = "state:Counter.count" ) # { count }
button ( data - action = "click->Counter.increment" ) + 1
button ( data - action = "click->Counter.decrement" ) - 1
// usage
+ counter ( 101119 )
+ counter ( 61316 )THYMEFEAF -Syntax Beispiel ?
// counter.html
< div
data-component =" Counter "
th:fragment =" Counter "
th:data-state =' |{"count":${count}, "isEven": ${count % 2 == 0}}| '
>
< p data-bind =" state:Counter.count " th:text =" ${count} " > </ p >
< button data-action =" click->Counter.increment " >
+1
</ button >
< button data-action =" click->Counter.decrement " >
-1
</ button >
</ div >
// usage
< th:block th:replace =" ./counter.html :: Counter(count: 1289) " />
< th:block th:replace =" ./counter.html :: Counter(count: 491) " />Beispiel für Razor -Syntax ⚔️ bald kommen ...
Ruby on Rails Syntax Beispiel ? bald kommen ...
BEWERTE SYNTAX BEISPIEL ? bald kommen ...
domponent [at] gmail [dot] com ( Bitte verwenden Sie den Thema Domponent Support oder wir werden nicht antworten )@domponent