Vuexに触発された1kb Progressive State Management Library。
このライブラリをNODE.JSモジュールとして、NPMレジストリを介して利用できるようにすることができます。
// With npm
$ npm install dragonbinder
// With yarn
$ yarn add dragonbinderまたは、ブラウザでスタンドアロン<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はプロキシを使用して、変異を犯さない限り変更できない「真実の単一の源」として状態を作成します。これは、プロパティを直接削除、変更、または追加できないことを意味します。これにより、州に行ったすべての変更を追跡することができます。
state財産によって初期の状態を提供しない場合、 Dragonbinderが作成します。
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' ) ;また、シングルトンが最初のストア定義を再利用しないようにしたい場合は、その状態を工場機能として宣言することができます。
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 ) ; // -> 4Vueと同様に、 Dragonbinderを使用すると、ゲッターを作成して、状態に基づいて計算されたプロパティを作成できます。このゲッターは、最初の議論として州を受け取り、他のすべてのゲッターは2番目に受け取ります。
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 ) ; // -> 1突然変異は状態を変える唯一の方法であり、突然変異を設計する際に次のポイントを考慮する必要があります。
Object.freezeを使用して深く凍結して直接変更を防ぎます。したがって、突然変異を使用して状態を変更している場合、第1レベルのプロパティのみを追加、変更、または削除できます。2番目のレベルのプロパティは読み取り専用です。 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' ) ;非同期関数を処理する必要がある場合は、アクションを使用する必要があります。そして、アクションは常にそれらを呼び出すことの結果として約束を返します。
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 secondコールバックをイベントに登録/登録できます。
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' ) ; すべてのイベントは、最初の引数としてストアインスタンスを受け取ります。
| イベント名 | いつ呼ばれますか | 場所で受け取った議論 |
|---|---|---|
| addlistener | イベントリスナーが追加されます | イベント名|リスナーが追加されました |
| Removelistener | イベントリスナーが削除されます | イベント名|リスナーが削除されました |
| セット | 州のプロパティが追加または変更され、モジュールが登録されているときにトリガーされます | プロパティ名|新しい値|古い価値 |
| 消去 | 状態のプロパティは削除され、モジュールが未登録のときにトリガーされます | プロパティ名|古い価値 |
| beforecommit | 呼び出されたメソッドをコミットし、突然変異を適用する前に | 突然変異名| (...)突然変異に渡された議論 |
| 専念 | 呼び出され、突然変異を適用した後のコミット方法 | 突然変異名| (...)突然変異に渡された議論 |
| beforedispatch | 呼び出して、アクションを適用する前にディスパッチメソッド | アクション名| (...)アクションに渡された議論 |
| 急送 | 呼び出されたディスパッチメソッドとアクションを適用した後 | アクション名| (...)アクションに渡された議論 |
| ゲッター | ゲッターが呼ばれます | ゲッター名|ゲッターの価値 |
| プラグイン | プラグインが追加されています | プラグインが追加されました| (...)プラグインに渡されたオプション |
| RegisterModule | モジュールが登録されています | 名前空間登録|モジュール定義|定義で作成されたストア |
| UnregisterModule | モジュールは未登録です | 登録されていない名前空間|定義で作成されたストア |
Vuexと同様に、 Dragonbinderを使用すると、ストアをモジュールに分割でき、各モジュールには、より多くのネストされたモジュールを含む独自のストア定義を含めることができます。
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また、ストアが作成された後、 registerModuleとunregisterModuleメソッドでモジュールを登録/登録することができます。
モジュールの登録を解除すると、最初のネストされたモジュールのみが登録されていないことを考慮してください。
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 各モジュールは他のストアと同様に動作しますが、Vuexとは異なり、すべてのDragonbinderモジュールは設計によって名前が付けられています。根の突然変異、アクション、またはモジュールを使用してゲッターを追加するオプションはありません。したがって、モジュールの突然変異、アクション、またはゲッターを呼び出すときは、そのフルネームスペースを提供する必要があります。
突然変異とゲッターの最初の議論は引き続き地方国家であり、行動とともに最初の議論はローカルコンテキスト/ストアになります。
ゲッターは、ルート状態とルートゲッターを3番目と4番目の引数として取得します。
アクションは、ローカルコンテキストのrootStoreプロパティによってルートコンテキストにアクセスします。
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には、シンプルだが強力なプラグインシステムが付属しています。プラグインを使用して、コア機能を拡張するか、完全に変更することができます。
let store = new Dragonbinder ( ) ;
store . use ( myPlugin , ... options ) ; Dragonbinderプラグインは、ストアインスタンスで最初の引数として呼び出される単一の関数をエクスポートするモジュールであり、オプションでは渡されたオプションがある場合はオプションです。
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
} ;
} ; https://masquerade-circus.github.io/dragonbinder/?apiでドキュメントを確認してください
貢献ガイドを確認してください:https://masquerade-circus.github.io/dragonbinder/?content=contributing
yarn devを使用して、すべての変更についてライブラリを視聴してコンパイルします。yarn buildを使用してライブラリを構築します。yarn testを使用して、テストを1回だけ実行します。yarn dev:testを使用して、ライブラリとテストの変更を監視するテストを実行します。yarn dev:test:nycを使用して、テストを実行して変更を監視し、最後にテストカバレッジを取得します。yarn docsを使用してドキュメントを作成します。yarn docs:watchして再構築します。yarn docs:serve 。 著者:マスカレードサーカス。ライセンスapache-2.0