1 كيلو بايت مكتبة إدارة الدولة التقدمية مستوحاة من Vuex.
يمكنك الحصول على هذه المكتبة كوحدة 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 ) // -> 1يستخدم Dragonbinder الوكلاء لإنشاء حالة كمصدر واحد للحقيقة "لا يمكن تغييره إلا إذا ارتكبت طفرة. هذا يعني أنه لا يمكنك حذف خاصية أو تعديلها أو إضافة خاصية مباشرة. هذا يسمح لنا بتتبع جميع التغييرات التي أجريناها على الدولة.
إذا لم تقم بتقديم حالة أولية من قبل خاصية 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' ) ;أيضًا ، إذا كنت ترغب في تجنب Singletons لإعادة استخدام تعريف المتجر الأولي الخاص بك ، فيمكنك إعلان حالتها كدالة للمصنع.
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 ) ; // -> 4كما هو الحال مع Vue ، مع DragonBinder ، يمكنك إنشاء getters لإنشاء خصائص محسوبة على أساس الحالة. سيتلقى هذا getters الدولة كحجة أولى وجميع getters الآخرين في الثانية.
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 لمنع التغييرات المباشرة. لذلك ، عندما تقوم بتغيير الحالة باستخدام طفرة ، يمكنك إضافة أو تعديل أو حذف خصائص المستوى الأول فقط ، سيتم قراءة خصائص المستوى الثاني فقط. 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' ) ;إذا كنت بحاجة إلى التعامل مع وظائف ASYNC ، فيجب عليك استخدام الإجراءات. وستقوم الإجراءات دائمًا بإرجاع الوعد نتيجة لاتصالهم.
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 | تمت إضافة مستمع حدث | اسم الحدث | وأضاف المستمع |
| الإزالة | تمت إزالة مستمع حدث | اسم الحدث | تم إزالة المستمع |
| تعيين | تتم إضافة خاصية للدولة أو تعديلها ، كما يتم تسجيلها عند تسجيل الوحدة النمطية | اسم الخاصية | قيمة جديدة | القيمة القديمة |
| يمسح | يتم حذف خاصية للدولة ، كما يتم تشغيلها عندما تكون الوحدة غير مسجلة | اسم الخاصية | القيمة القديمة |
| beforecommit | طريقة الالتزام تسمى وقبل تطبيق الطفرة | اسم طفرة | (...) تم تمرير الحجج إلى الطفرة |
| يقترف | تسمى طريقة الالتزام وبعد تطبيق الطفرة | اسم طفرة | (...) تم تمرير الحجج إلى الطفرة |
| beforedispatch | طريقة الإرسال المسمى وقبل تطبيق الإجراء | اسم الإجراء | (...) تم تمرير الحجج إلى الإجراء |
| إرسال | تسمى طريقة الإرسال وبعد تطبيق الإجراء | اسم الإجراء | (...) تم تمرير الحجج إلى الإجراء |
| getter | يسمى getter | اسم getter | قيمة getter |
| البرنامج المساعد | تمت إضافة البرنامج المساعد | وأضاف البرنامج المساعد | (...) تم تمرير الخيارات إلى البرنامج المساعد |
| 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 أيضًا ، بعد إنشاء المتجر ، يمكنك تسجيل/UNGISTER MODULES مع أساليب 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 بواسطة الأسماء حسب التصميم. لا يوجد خيار لإضافة طفرات جذر أو أفعال أو getters مع وحدة نمطية. لذلك ، عندما تتصل بطفرة الوحدة النمطية أو الإجراء أو الإجراء ، تحتاج إلى توفير مساحة اسمها الكاملة.
ستستمر الحجة الأولى للطفرات والغتل في الدولة المحلية ، ومع الإجراءات ، ستكون الحجة الأولى هي السياق/المتجر المحلي.
سيحصل Getters على حالة الجذر و getters الجذر كحجيلات ثالثة ورابعة.
ستصل الإجراءات إلى سياق الجذر بواسطة خاصية 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 Doeيأتي Dragonbinder مع نظام إضافي بسيط ولكنه قوي. يمكنك تمديد وظائفها الأساسية أو تغييرها تمامًا عن طريق الاستفادة من الإضافات.
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 لتشغيل الاختبارات مرة واحدة فقط.yarn dev:test لتشغيل الاختبارات مشاهدة التغييرات على المكتبة والاختبارات.yarn dev:test:nyc لتشغيل الاختبارات مشاهدة التغييرات والحصول على تغطية الاختبار في النهاية.yarn docs لبناء الوثائق.yarn docs:watch لمشاهدة الوثائق وإعادة بناءها على كل تغيير إلى المكتبة أو ملفات MD.yarn docs:serve لرؤية الوثائق التي تم إنشاؤها محليًا. المؤلف: سيرك تنكر. ترخيص Apache-2.0