مدیریت state در یک برنامه پر از کامپوننت، میتواند سخت باشد. Facebook به سختترین روش با این مسئله رو به رو شد و الگوی Flux را به وجود آورد، که این الگو چیزی است که Vuex بر پایه آن ساخته شده است. Vuex در واقع الگو و کتابخانه مدیریت state مختص خود Vue است.
در این آموزش، به این که چرا یک برنامه ممکن است به Vuex نیاز داشته باشد و این که چگونه میتواند برنامه شما را تقویت کند، نگاه خواهیم داشت.
موقعیت مربوط به مدیریت state
وقتی که درباره state صحبت میکنیم، منظورمان دادههایی است که کامپوننتهای شما به آنها تکیه کرده، و رندر میکنند. مواردی مانند پستهای بلاگ، آیتمهای لیست یادداشت و... بدون Vuex همینطور که برنامه شما رشد میکند، هر کامپوننت Vue ممکن است نسخه state مختص خود را داشته باشد.
اما اگر یک کامپوننت state خود را تغییر دهد، و یک کامپوننت نیاز داشته باشد که به آن مقدار state جدید دسترسی داشته باشد، ما به راهی نیاز داریم که این دو کامپوننت با هم ارتباط برقرار کنند.
ما میتوانیم با استفاده از رویدادها با آن state به سمت بالا در ساختار درختی کامپوننتها ارتباط برقرار کنیم، و با منتقل کردن propها به همراه آن، به سمت پایین ارتباط برقرار کنیم؛ اما همینطور که مقیاس برنامه ما گستردهتر میشود، این مسئله میتواند بیش از حد پیچیده شود.
با گذر زمان «ساختار درختی خانواده» کامپوننتها ممکن است بسیار بزرگ شود، و در هنگام تلاش برای نگهداری و ردگیری آن state در برنامه در حال رشد شما، یک سردرگمی ذهنی ایجاد کند.
به جای این که هر کدام از کامپوننتهای ما state محلی خود را داشته باشند، ما میتوانیم تمام stateهای خود را در یک مکان یکی کنیم. یک مکان global که state فعلی کل برنامه ما را در خود نگه میدارد؛ یک منبع یکتا برای حقیقت.
Global State: تنها منبع حقیقت
Vuex این منبع یگانه حقیقت را برای ما فراهم میکند. همینطور که ما شروع به ذخیره سازی state در آن مینماییم، state ما بسیار مرتبتر و بسیار منطقیتر میشود. حال هر کامپوننتی که به Global state ما تکیه میکند، میتواند دسترسی مستقیم به آن داشته باشد. دیگر نیازی به منتقل کردن state به بالا و پایین نیست.
از آنجایی که Vuex با استفاده از Vue نوشته شده است، Vuex State واکنشپذیر است. درست به مانند دادههای نمونه Vue.
وقتی که یک کامپوننت Vuex state را بروزرسانی میکند، کامپوننتهای دیگر میتوانند منتظر تغییر state باشند، و سپس میتوانند بر پایه آن تغییر state (و مقدار state جدیدی که دریافت کردند) پاسخ دهند.
اما فقط یکی کردن state در یک منبع، مشکل مدیریت state ما را به طور کامل حل نمیکند. برای مثال، چه اتفاقی میافتد وقتی که چند کامپوننت state را به روشهای مختلف و از مکانهای مختلفی دستکاری میکنند؟
تغییرات اعمال شده به state ما میتوانند غیر قابل پیشبینی و غیر قابل ردیابی باشند. ما به استاندارد سازی بیشتری نیاز داریم.
یک الگوی مدیریت state
به همین علت است که Vuex یک الگوی مدیریت state کامل برای یک راه ساده و استاندارد سازی شده، در جهت اعمال تغییرات state فراهم میکند. و اگر شما با Vue آشنا هستید، Vuex باید ظاهر آشنایی برایتان داشته باشد.
درست به مانند Vue که یک نمونه Vue ریشه ساخته شده با استفاده از new Vue را فراهم میکند، Vuex یک مخزن ساخته شده با استفاده از new Vuex.Store را فراهم میکند.
درحالیکه نمونه Vue یک ویژگی data دارد، مخزن Vuex هم state را دارد. هر دوی آنها واکنشپذیر هستند.
و در حالیکه نمونه مورد نظر متدهایی دارد و این متدها میتوانند دادهها را بروزرسانی کنند، یک مخزن Vuex هم actionهایی را به همراه دارد، که میتوانند در مدیریت بروزرسانی state کمک کنند.
و در حالیکه نمونه مورد نظر ویژگیها را محاسبه کرده است، مخزن Vuex هم getterهایی دارد که ما را قادر میسازند تا به state فیلتر شده، نشات گرفته یا محاسبه شده دسترسی داشته باشیم.
تفاوت مخزن Vuex این است که این مخزن همچنین جهشهایی (mutations) را به همراه دارد. علت این که گفتم «actionها میتوانند در بروزرسانی state کمک کنند»، این است که actionها لزوما متدهایی هستند که جهشها را فراخوانی میکنند. حال جهشها هم در واقع چیزهایی هستند که Vuex State را بروزرسانی میکنند.
جهشها همچنین ما را قادر میسازند تا تغییرات state خود را ردگیری کنیم. و اگر ما در حال استفاده از Vue DevTools باشیم، در تب Vuex حتی میتوانیم یک ضبط دارای زمان سنج از تمام جهشهایی که از طریق lifecycle برنامهمان اجرا شده بودند را به دست بیاوریم. به این مسئله «خطایابی سفر در زمان» (time-travel-debugging) میگویند، و DevTools حتی به ما نشان میدهد که state در آن زمانها چه چیزی بود.
جهشهایی درون actionها
قرار دادن جهشها در actionها، ما را قادر میسازد تا نوعی منطق به دور فراخوانیهای جهش خود قرار دهیم.
برای مثال: ممکن است بخواهیم یک منطق شرطی را اجرا کنیم تا تعیین کنیم که آیا یک تغییر state نیاز است که پیش بیاید یا نه. اگر نه، ممکن است ما جهش مورد نظر را اجرا نکنیم. حتی ممکن است در عوض به طور پیشفرض به سراغ یک جهش ثانویه برویم. پس همانطور که میتوانید ببینید، actionها ما را قادر میسازند تا چند جهش را داخل منطق مشابهی جمعبندی کنیم. این راه، لزوما راه ما برای مدیریت تغییرات state خود در سطح برنامه است.
یک مخزن Vuex
حال بیایید به یک مخزن Vuex نمونه نگاهی داشته باشیم:
ما در state خود، یک ویژگی loadingStatus به همراه آرایهای از یادداشتها داریم.
در زیر آن، جهش SET_LOADING_STATUS ما را قادر میسازد تا state خود به نام loadingStatus را بروزرسانی کنیم. و جهش SET_TODOS، state ما را برابر با یادداشتهایی که از یک فراخوانی API در action زیرین دریافت میکنیم، قرار میدهد.
در اینجا action ما چندین قدم دارد:
اول، این action جهش SET_LOADING_STATUS را اعزام میکند تا loadingStatus را برابر با loading قرار دهد.
سپس، یک فراخوانی API را ارسال میکند...
... و وقتی که پاسخ مورد نظر بر میگردد، مجددا جهش SET_LOADING_STATUS را اعزام میکند تا وضعیت isLoading را برابر با notLoading قرار دهد.
در آخر، این action جهش SET_TODOS را اعزام میکند تا state یادداشتهای ما را برابر با پاسخی که از API خود دریافت کردیم، قرار دهد.
حال اگر به این قابلیت نیاز داشته باشیم که یادداشتهای دارای برچسب «انجام شده» را به دست بیاوریم، میتوانیم از یک getter برای آن استفاده کنیم، که میتواند برنامه نویسی شود تا state یادداشتهای ما را فیلتر کند و فقط state مشخصی که میخواهیم را به دست بیاورد.
حال که الگوی Vuex را بررسی کردهایم، بیایید آن را در عمل ببینیم.
Vuex در عمل
مقالات مرتبط:
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید