vuex

مدیریت state ها تو پروژه هایی که تعداد زیادی کامپوننت داره میتونه گاها سخت بشه. فیسبوک از یک پترن به اسم flux استفاده کرد، که vuex بر اساس آن طراحی شده است. واستون ممکنه سوال پیش بیاد و بخواین بیشتر راجب Flux بدونین.فلاکس، یک الگو معماری هست که توسط فیسبوک برای ساخت SPA(Single page Application)، پیشنهاد شده و برنامه رو به چند بخش تقسیم میکنهوVuex، یک کتابخانه و یک state management pattern هست که کار ما رو برای مدیریت state ها تو اپلیکیشن راحت تر میکنه.وقتی از State صحبت میکنم منظورم دیتا هایی هست که اپلیکشن وابسته به اونهاست. مثلا مثل پست های بلاگ یا آیتم های یک تودولیست و .... وقتی اپلیکیشن شما بزرگ و بزرگتر میشه، هر کامپوننت یک ورژن از دیتای خودش رو داره و اگر این دیتا تو یکی از کامپوننت ها تغییر کنه باید تو بقیه کامپوننت های وابسته هم تغییر کنه. در حالت عادی برای این کار از emit کردن event ها و پاس دادن props ها برای share کردن دیتا استفاده میکنیم و این کار با افزایش کامپوننت ها و بزرگ تر شدن اونها سخت تر میشه.چی میشه اگه بتونیم همه ی state هارو در یه جا مدیریت کنیم؟ یک فایلی که state کل اپلیکیشن رو داشته باشه؟ در واقع این همون چیزیه که VUEX برای ما انجام میده. و هر کامپوننت به صورت مستقل میتونه به اون state ها دسترسی داشته باشه. و مهم تر از همه اینکه این state گلوبال ما reactive هست. یعنی وقتی یک کامپوننت sate رو آپدیت میکنه، بقیه کامپوننت هایی که از اون دیتا استفاده میکنن هم با خبر تغییرات میشن و مقدار اون دیتا در کل اپلیکیشن تو همه ی کامپوننت ها آپدیت میشه.تو هر کامپوننت ما می تونیم از fetchTodods به صورت زیر استفاده کنیمthis.$store.dispatch('fetchTodos')اینطوری کامپوننت به تمام کد های داخل fetchTodos دسترسی داره و کاری که میکنه اینه که اول loading رو برابر با status یعنی true قرار میده و سپس دیتا رو فتچ میکنیم و وقتی که دیتا رو از api گرفتیم، loading رو برابر با false قرار میدیم. و در آخر SET_TODOS رو کامیت میکنیم که برابر آرایه todos رو برابر ریسپانسی که از API گرفتیم قرار میده.حالا ببینیم که تو هر کامپوننت چجوری میتونیم به دیتای داخل استور دسترسی داشته باشیم؟ میتونیم به صورت بالا تو هر کامپوننت به استیت ها دسترسی داشته باشیم. یا میتونیم به صورت زیر از mapState استفاده کنیم.یا یا میتونیم اسم state هارو در یک آرایه به صورت زیر بنویسیم و همه چی همچنان درست کار خواهد کرد حالا بیاید ببینیم چطوری میتونیم توسط Getters به state ها دسترسی داشته باشیم. مثلا اگر بخوایم به length آرایه todos دسترسی داشته باشیم، میتونیم ازcomputed: { todosLength(){ return this.$store.todos.length } } اون رو به دست بیاریم یا میتونیم از Getters در استور استفاده کنیم.getters: { todosLength: state=>{ return state.todos.length } }Dynamic getters‍‍// In the store getters:{ getTodoById: state=> id=>{ return state.todos.find(todo=> todo.id === id) } }و در کامپوننت ازون به این صورت استفاده میکنیم<template> <div>{{ getTodo(1) }}</div> </template> export default{ computed: { getTodo(){ return this.$store.getters.getEventById } } } همونطور که از mapState استفاده کردیم، میتونیم از mapGetters برای دسترسی به getter ها استفاده کنیم.حالا بیاین راجب Mutation و Actions بیشتر صحبت کنیم.توسط Mutations میتونیم state اپلیکیشن رو آپدیت یا mutate کنیم. مثلا اگر یک counter داشته باشیم که بخوایم با هربار کلیک کردن یکی به اون اضافه کنیم، میتونیم توسط mutations به صورت زیر این کار رو انجام بدیم// In the store state: { counter: 0 }, mutations: INCREMENT_COUNT(state , value){ state.count += value } }میوتیشن تو اولین آرگیومنت state رو میگیره و میتونیم با اون state count رو آپدیت کنیم. حالا باید با هر بار کلیک شدن INCREMENT_COUNT ،button رو صدا بزنیم.تفاوت mutations و actions این هست که، mutations به صورت synchronous، یعنی پشت سر هم اجرا میشه ولی actions به صورت Asynchronous اجرا میشن. یعنی ترتیب execute شدن کد ها الزاما به ترتیبی که نوشته شدن نیست. و ما از action ها برای commit کردن mutations استفاده میکنیم و بهتره که همیشه اینکارو انجام بدیم که تو مثال زیر باهم میبینیم چطوری ;)یه مثال بخوام بزنم، مثلا فکر کنید به دوستتون پیام میدین و ازش میپرسید که آیا میتونه برای شما یه خودکار بیاره یا نه... عمل خودکار آوردن برای شما مثل mutations هست، و درخواست شما از دوستتون برای خودکار شبیه به actions هست.کد counter که نوشته بودیم رو میتونیم به صورت زیر ریفکتور کنیم. در store یه action اضافه میکنیم. action ها یک آبجکت context به عنوان اولین آرگیومنت میگیرن که شامل همه ی property ها توی vuex store هستن و مثلا با اون میتونن به state ها دسترسی داشته باشن یا یک mutation رو commit کنن و ...actions: { updateCount(context, value){ if(context.state.user){ context.commit(&quotINCREMENT_COUNT&quot, value) } } }و حالا تو کامپوننت متد incrementCount رو به صورت زیر آپدیت میکنیم:incrementCounter(){ this.$store.dispatch('updateCount', 2) }دومین آرگیومنت (عدد 2)، به عنوان payload، به action پاس داده میشه و با هربار کلیک کردن button، مقدار count دو واحد اضافه میشه.