1KB Progressive State Management Library inspiriert von Vuex.
Sie können diese Bibliothek als Node.js -Modul über die NPM -Registrierung erhalten:
// With npm
$ npm install dragonbinder
// With yarn
$ yarn add dragonbinder Oder Sie können es eigenständig im Browser verwenden mit: <script src="https://cdn.jsdelivr.net/npm/dragonbinder"></script>
const Dragonbinder = require ( 'dragonbinder' ) ;
const store = new Dragonbinder ( {
state : {
count : 0
} ,
mutations : {
increment ( state ) {
state . count ++
}
}
} ) ;
store . commit ( 'increment' ) ;
console . log ( store . state . count ) // -> 1Dragonbinder Verwenden Sie Proxys, um einen Zustand als "einzelne Quelle der Wahrheit" zu erstellen, die nicht geändert werden kann, wenn Sie eine Mutation begehen. Dies bedeutet, dass Sie eine Eigenschaft nicht direkt löschen, ändern oder hinzufügen können. Dies ermöglicht es uns, alle Änderungen im Auge zu behalten, die wir am Staat vorgenommen haben.
Wenn Sie vom state Property Dragonbinder keinen Anfangszustand anbieten, erzeugen Sie einen.
const store = new Dragonbinder ( {
state : {
count : 0
} ,
mutations : {
addProperty ( state , value ) {
state . hello = 'world' ;
} ,
modifyProperty ( state ) {
state . count ++
} ,
removeProperty ( state ) {
delete state . count ;
}
}
} ) ;
// This will throw errors
store . state . hello = 'world' ;
store . state . count ++ ;
delete state . count ;
// This will work as expected
store . commit ( 'addProperty' ) ;
store . commit ( 'modifyProperty' ) ;
store . commit ( 'removeProperty' ) ;Wenn Sie Singletons vermeiden möchten, um Ihre erste Geschäftdefinition wiederzuverwenden, können Sie seinen Zustand als Fabrikfunktion deklarieren.
const myStoreDefinition = {
state ( ) {
return {
count : 1
}
} ,
mutations : {
increment ( state , payload ) {
state . count = state . count + payload ;
}
}
} ;
const store1 = new Dragonbinder ( myStoreDefinition ) ;
const store2 = new Dragonbinder ( myStoreDefinition ) ;
store1 . commit ( 'increment' , 5 ) ;
store2 . commit ( 'increment' , 3 ) ;
console . log ( store1 . state . count ) ; // -> 6
console . log ( store2 . state . count ) ; // -> 4Wie bei Vue können Sie mit Dragonbinder Getter erstellen, um berechnete Eigenschaften basierend auf dem Status zu erstellen. Diese Getter erhalten den Staat als erstes Argument und alle anderen Getter als zweites.
const store = new Dragonbinder ( {
state : {
todos : [
{
content : 'First' ,
completed : false
} ,
{
content : 'Second' ,
completed : true
}
]
} ,
getters : {
completed ( state ) {
return state . todos . filter ( item => item . completed ) ;
} ,
completedCount ( state , getters ) {
return getters . completed . length ;
}
}
} ) ;
console . log ( store . getters . completed ) ; // -> { content: 'Second', completed: true }
console . log ( store . getters . completedCount ) ; // -> 1Mutationen sind die einzige Möglichkeit, den Zustand zu ändern, und Sie müssen die nächsten Punkte beim Entwerfen von Mutationen berücksichtigen.
Object.freeze tief eingefroren. Freie, um direkte Änderungen zu verhindern. Wenn Sie den Zustand mit einer Mutation ändern, können Sie nur Eigenschaften der ersten Ebene hinzufügen, ändern oder löschen. Die Eigenschaften der zweiten Ebene werden nur gelesen. const store = new Dragonbinder ( {
state : {
hello : {
name : 'John Doe'
}
} ,
mutations : {
changeNameError ( state , payload ) {
state . hello . name = payload ;
} ,
changeNameOk ( state , payload ) {
state . hello = { ... state . hello , name : payload } ;
} ,
changeNameTo ( state , ... args ) {
state . hello = { ... state . hello , name : args . join ( ' ' ) } ;
}
}
} ) ;
// This will throw an assign to read only property error
store . commit ( 'changeNameError' , 'Jane Doe' ) ;
// This will work as expected
store . commit ( 'changeNameOk' , 'Jane Doe' ) ;
// You can pass any number of arguments as payload
store . commit ( 'changeNameTo' , 'Jane' , 'Doe' ) ;Wenn Sie asynchronisierte Funktionen erledigen müssen, müssen Sie Aktionen verwenden. Und Aktionen werden immer ein Versprechen zurückgeben, wenn sie angerufen werden.
const store = new Dragonbinder ( {
state : {
count : 0
} ,
mutations : {
increment ( state ) {
state . count ++
}
} ,
actions : {
increment ( state ) {
return new Promise ( ( resolve ) => {
setTimeout ( ( ) => {
store . commit ( 'increment' ) ;
resolve ( ) ;
} , 1000 ) ;
} )
}
}
} ) ;
store . dispatch ( 'increment' ) . then ( ( ) => console . log ( store . state . count ) ) ; // -> 1 after one secondSie können Rückrufe zu Ereignissen registrieren/nicht registrieren.
const store = new Dragonbinder ( {
state : {
count : 0
} ,
mutations : {
increment ( state ) {
state . count ++
}
}
} ) ;
// Add a named listener
let namedListener = ( store , prop , newVal , oldVal ) => console . log ( `The property ${ prop } was changed from ${ oldVal } to ${ newVal } ` ) ;
store . on ( 'set' , namedListener ) ;
// Add an anonymous listener
let removeAnonymousListener = store . on ( 'set' , ( ) => console . log ( 'Anonymous listener triggered' ) ) ;
// Committing increment will trigger the listener
store . commit ( 'increment' ) ;
// $ The property count was changed from 0 to 1
// $ Anonymous listener triggered
// Remove a named listener
store . off ( 'set' , namedListener ) ;
// Remove an anonyous listener
removeAnonymousListener ( ) ;
// Committing increment will do nothing as the listeners are already removed
store . commit ( 'increment' ) ; Alle Veranstaltungen erhalten die Geschäftsinstanz als erstes Argument.
| Ereignisname | Es heißt wann | Argumente, die nach Ort erhalten wurden |
|---|---|---|
| Addierener | Ein Event -Hörer wird hinzugefügt | Ereignisname | Hörer fügte hinzu |
| Entfernung | Ein Event -Hörer wird entfernt | Ereignisname | Hörer entfernt |
| Satz | Eine Eigenschaft des Staates wird hinzugefügt oder geändert, ebenfalls ausgelöst, wenn ein Modul registriert ist | Eigenschaftsname | Neuer Wert | Alter Wert |
| löschen | Eine Eigenschaft des Staates wird gelöscht und auch ausgelöst, wenn ein Modul nicht registriert ist | Eigenschaftsname | Alter Wert |
| Beecommit | Commit -Methode aufgerufen und vor dem Anwenden der Mutation anwenden | Mutationsname | (...) Argumente, die an die Mutation übergeben wurden |
| begehen | Commit -Methode, die aufgerufen wird und nach dem Anwenden der Mutation | Mutationsname | (...) Argumente, die an die Mutation übergeben wurden |
| vorgespüren | Versandmethode aufgerufen und vor dem Anwenden der Aktion anwenden | Aktionsname | (...) Argumente, die an die Aktion übergeben wurden |
| versenden | Absendungsmethode aufgerufen und nach dem Anwenden der Aktion | Aktionsname | (...) Argumente, die an die Aktion übergeben wurden |
| Getter | Ein Gettter heißt | Getter -Name | Wert des Getters |
| Plugin | Ein Plugin wird hinzugefügt | Plugin hinzugefügt | (...) Optionen, die an das Plugin übergeben wurden |
| RegisterModule | Ein Modul ist registriert | Namespace registriert | Moduldefinition | Speicher mit der Definition erstellt |
| unregisterModul | Ein Modul ist nicht registriert | Namespace nicht registriert | Speicher mit der Definition erstellt |
Wie Vuex können Sie mit Dragonbinder Ihr Geschäft in Module unterteilen und jedes Modul kann eine eigene Speicherdefinition enthalten, einschließlich mehr verschachtelter Module.
const moduleA = {
state : { ... } ,
mutations : { ... } ,
actions : { ... } ,
getters : { ... }
}
const moduleB = {
state : { ... } ,
mutations : { ... } ,
actions : { ... } ,
getters : { ... }
modules : {
a : moduleA
}
}
const store = new Dragonbinder ( {
modules : {
b : moduleB
}
} ) ;
console . log ( store . state . b ) // -> `moduleB`'s state
console . log ( store . state [ 'b.a' ] ) // -> `moduleA`'s state Nach dem Erstellen des Speichers können Sie Module mit den Methoden registerModule und unregisterModule " registrieren/nicht registrieren.
Bedenken Sie, dass bei der Nichtregistrierung eines Moduls nur seine anfänglichen verschachtelten Module damit nicht registriert werden.
const moduleA = {
state : { ... } ,
mutations : { ... } ,
actions : { ... } ,
getters : { ... }
}
const moduleB = {
state : { ... } ,
mutations : { ... } ,
actions : { ... } ,
getters : { ... } ,
modules : {
a : moduleA
}
}
const moduleC = {
state : { ... } ,
mutations : { ... } ,
actions : { ... } ,
getters : { ... }
}
const store = new Dragonbinder ( ) ;
store . registerModule ( 'b' , moduleB ) ;
store . registerModule ( 'b.c' , moduleC ) ;
console . log ( store . state . b ) // -> `moduleB`'s state
console . log ( store . state [ 'b.a' ] ) // -> `moduleA`'s state
console . log ( store . state [ 'b.c' ] ) // -> `moduleC`'s state
store . unregisterModule ( 'b' ) ;
console . log ( store . state . b ) // -> undefined
console . log ( store . state [ 'b.a' ] ) // -> undefined
console . log ( store . state [ 'b.c' ] ) // -> `moduleC`'s state Jedes Modul wird sich wie jedes andere Geschäft verhalten, aber im Gegensatz zu Vuex werden alle Dragonbinder -Module von Design namensspasiert. Es gibt keine Möglichkeit, Stammmutationen, Aktionen oder Gettter mit einem Modul hinzuzufügen. Wenn Sie also eine Modulmutation, Aktion oder Getter anrufen, müssen Sie seinen vollständigen Namespace angeben.
Das erste Argument für Mutationen und Getter wird weiterhin der lokale Staat sein, und mit Aktionen wird das erste Argument der lokale Kontext/der lokale Geschäft sein.
Getters erhalten den Wurzelstatus und die Stammgeräte als dritte und vierte Argumente.
Aktionen werden durch die rootStore -Eigenschaft des lokalen Kontextes auf den Stammkontext zugreifen.
const moduleA = {
state : {
hello : 'world'
} ,
mutations : {
sayHello ( state , payload ) {
state . hello = payload ;
}
} ,
actions : {
change ( store , payload ) {
store . commit ( 'sayHello' , payload ) ;
store . rootStore . commit ( 'increment' ) ;
}
} ,
getters : {
hello ( state , getters , rootState , rootGetters ) {
return `You have said hello ${ rootState . count } times to ${ state . hello } ` ;
}
}
} ;
const store = new Dragonbinder ( {
state : {
count : 0
} ,
mutations : {
increment ( state ) {
state . count ++ ;
}
} ,
modules : {
a : moduleA
}
} ) ;
store . dispatch ( 'a.change' , 'John Doe' ) ;
console . log ( store . getters [ 'a.hello' ] ) ; // -> You have said hello 1 times to John Doe
console . log ( store . state . count ) // -> 1
console . log ( store . state . a . hello ) // -> John DoeDragonbinder verfügt über ein einfaches, aber leistungsstarkes Plugin -System. Sie können seine Kernfunktionalität erweitern oder sie vollständig ändern, indem Sie Plugins verwenden.
let store = new Dragonbinder ( ) ;
store . use ( myPlugin , ... options ) ; Ein Dragonbinder -Plugin ist ein Modul, das eine einzige Funktion exportiert, die mit der Store -Instanz als erstes Argument und optional mit den übergebenen Optionen aufgerufen wird, falls vorhanden.
const Dragonbinder = require ( 'dragonbinder' ) ;
const myPlugin = ( store , ... options ) => {
Dragonbinder . myGlobalMethod = function ( ) {
// Awesome code here
} ;
Dragonbinder . fn . myPrototypeMethod = function ( ) {
// Awesome code here
} ;
store . myLocalMethod = function ( ) {
// Awesome code here
} ;
} ; Überprüfen Sie die Dokumente unter: https://masquerade-circus.github.io/dragonbinder/?api
Überprüfen Sie den beitragenden Handbuch unter: https://masquerade-circus.github.io/dragonbinder/?content=contributing
yarn dev um die Bibliothek bei jeder Änderung zu beobachten und zu kompilieren.yarn build , um die Bibliothek zu erstellen.yarn test , um Tests nur einmal auszuführen.yarn dev:test , um die Tests auszuführen, die Änderungen an Bibliothek und Tests beobachten.yarn dev:test:nyc um die Tests durchzuführen, um Änderungen zu beobachten und die Testabdeckung endlich zu erhalten.yarn docs , um die Dokumentation zu erstellen.yarn docs:watch die Dokumentation zu jeder Änderung der Bibliothek oder der MD -Dateien, um die Dokumentation zu beobachten und neu aufzubauen.yarn docs:serve die generierte Dokumentation lokal an. Autor: Maskerade Circus. Lizenz Apache-2.0