1KB Perpustakaan Manajemen Negara Progresif Terinspirasi oleh Vuex.
Anda bisa mendapatkan perpustakaan ini sebagai modul Node.js yang tersedia melalui NPM Registry:
// With npm
$ npm install dragonbinder
// With yarn
$ yarn add dragonbinder Atau Anda dapat menggunakannya mandiri di browser dengan: <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 menggunakan proxy untuk menciptakan keadaan sebagai "sumber kebenaran tunggal" yang tidak dapat diubah kecuali Anda melakukan mutasi. Ini berarti bahwa Anda tidak dapat menghapus, memodifikasi, atau menambahkan properti secara langsung. Ini memungkinkan kami untuk melacak semua perubahan yang kami buat ke negara bagian.
Jika Anda tidak memberikan keadaan awal oleh properti state DragonBinder akan membuatnya.
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' ) ;Juga, jika Anda ingin menghindari singleton untuk menggunakan kembali definisi toko awal Anda, Anda dapat menyatakan keadaannya sebagai fungsi pabrik.
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 ) ; // -> 4Seperti halnya Vue, dengan DragonBinder Anda dapat membuat getters untuk membuat properti yang dihitung berdasarkan keadaan. Getters ini akan menerima negara sebagai argumen pertama dan semua getter lainnya sebagai yang kedua.
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 ) ; // -> 1Mutasi adalah satu -satunya cara untuk mengubah keadaan dan Anda harus mempertimbangkan poin berikutnya saat merancang mutasi.
Object.freeze untuk mencegah perubahan langsung. Jadi, ketika Anda mengubah status dengan menggunakan mutasi, Anda dapat menambahkan, memodifikasi atau menghapus hanya properti tingkat pertama, properti tingkat kedua hanya akan dibaca. 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' ) ;Jika Anda perlu menangani fungsi async, Anda harus menggunakan tindakan. Dan tindakan akan selalu mengembalikan janji sebagai hasil dari memanggil mereka.
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 secondAnda dapat mendaftarkan/membatalkan register panggilan balik ke acara.
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' ) ; Semua acara menerima contoh toko sebagai argumen pertama.
| Nama Acara | Itu disebut kapan | Argumen yang diterima berdasarkan tempat |
|---|---|---|
| addlistener | Sebuah pendengar acara ditambahkan | Nama Acara | Pendengar ditambahkan |
| Removelistener | Seorang pendengar acara dihapus | Nama Acara | Pendengar dihapus |
| mengatur | Properti negara ditambahkan atau dimodifikasi, juga dipicu saat modul terdaftar | Nama Properti | Nilai Baru | Nilai lama |
| menghapus | Properti negara dihapus, juga dipicu ketika suatu modul tidak terdaftar | Nama Properti | Nilai lama |
| Beforecommit | Metode melakukan yang dipanggil dan sebelum terapkan mutasi | Nama Mutasi | (...) Argumen yang diteruskan ke mutasi |
| melakukan | Metode melakukan yang dipanggil dan setelah menerapkan mutasi | Nama Mutasi | (...) Argumen yang diteruskan ke mutasi |
| Beforedispatch | Metode pengiriman dipanggil dan sebelum menerapkan tindakan | Nama tindakan | (...) Argumen yang diteruskan ke tindakan tersebut |
| menugaskan | Metode pengiriman dipanggil dan setelah menerapkan tindakan | Nama tindakan | (...) Argumen yang diteruskan ke tindakan tersebut |
| Getter | Seorang pengambil dipanggil | Nama pengambil | Nilai pengambil |
| plugin | Plugin ditambahkan | Plugin ditambahkan | (...) Opsi diteruskan ke plugin |
| Registermodule | Modul terdaftar | Namespace terdaftar | Definisi Modul | Toko dibuat dengan definisi |
| unregistermodule | Modul tidak terdaftar | Namespace tidak terdaftar | Toko dibuat dengan definisi |
Seperti Vuex, DragonBinder memungkinkan Anda untuk membagi toko Anda menjadi modul dan setiap modul dapat berisi definisi toko sendiri termasuk modul yang lebih bersarang.
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 Juga, setelah toko dibuat, Anda dapat mendaftar/membatalkan register modul dengan metode registerModule dan unregisterModule .
Pertimbangkan bahwa ketika Anda tidak mendaftar modul, hanya modul bersarang awal yang tidak akan terdaftar dengannya.
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 Setiap modul akan berperilaku seperti toko lainnya, tetapi, tidak seperti Vuex, semua modul DragonBinder dinamai oleh desain. Tidak ada opsi untuk menambahkan mutasi root, tindakan atau getter dengan modul. Jadi, ketika Anda memanggil mutasi, tindakan atau pengambil modul, Anda perlu menyediakan namespace penuh.
Argumen pertama untuk mutasi dan pengambil akan terus menjadi negara setempat, dan dengan tindakan argumen pertama adalah konteks/toko lokal.
Getters akan mendapatkan root state dan root getters sebagai argumen ketiga dan keempat.
Tindakan akan mengakses konteks root dengan properti rootStore dari konteks lokal.
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 hadir dengan sistem plugin yang sederhana namun kuat. Anda dapat memperluas fungsionalitas intinya atau mengubahnya sepenuhnya dengan memanfaatkan plugin.
let store = new Dragonbinder ( ) ;
store . use ( myPlugin , ... options ) ; Plugin DragonBinder adalah modul yang mengekspor fungsi tunggal yang akan dipanggil dengan instance Store sebagai argumen pertama dan secara opsional dengan opsi yang dilewatkan jika ada.
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
} ;
} ; Periksa dokumen di: https://masquerade-circus.github.io/dragonbinder/?api
Periksa panduan berkontribusi di: https://masquerade-circus.github.io/dragonbinder/?content=contributing
yarn dev untuk menonton dan mengkompilasi perpustakaan pada setiap perubahan pada itu.yarn build untuk membangun perpustakaan.yarn test untuk menjalankan tes hanya sekali.yarn dev:test untuk menjalankan tes menonton perubahan pada perpustakaan dan tes.yarn dev:test:nyc untuk menjalankan tes menonton perubahan dan akhirnya mendapatkan cakupan tes.yarn docs untuk membangun dokumentasi.yarn docs:watch untuk menonton dan membangun kembali dokumentasi pada setiap perubahan ke perpustakaan atau file MD.yarn docs:serve untuk melihat dokumentasi yang dihasilkan secara lokal. Penulis: Sirkus Masquerade. Lisensi APACHE-2.0