مرحبا يا هبر! أقدم لكم ترجمة مقال "إتقان Vuex - من صفر إلى بطل" لساناث كومار.
يعرّفها توثيق Vuex الرسمي على أنه نمط إدارة الدولة + مكتبة لتطبيقات Vue.js. لكن ماذا يعني ذلك؟ ما هو نمط إدارة الدولة؟
تخيل أنك تعمل على تطبيق ويب كبير يحتوي على مئات المسارات والمكونات. ألن يكون أسهل إذا تمكنا من تخزين جميع البيانات التي قد نحتاجها في أي تطبيق في وحدة تخزين مركزية واحدة؟

سيطلب كل مكون أو مسار داخل تطبيقنا بيانات من حالة Vuex ونقل البيانات التي تم تغييرها إلى الحالة.
في الجوهر ، يمكن النظر إلى حالة Vuex كمصدر الحقيقة الوحيد للتطبيق بأكمله.
يتم تخزين البيانات داخل الحالة ككائن JSON. على سبيل المثال:
state: { name: "John Doe", age: "28" }
ولكن كيف يمكن لمكوناتنا ومساراتنا الوصول إلى البيانات المخزنة في ولايتنا؟ للقيام بذلك ، نحتاج إلى تحديد الرسائل داخل مستودع Vuex الخاص بنا والذي سيعيد البيانات من المستودع إلى مكوناتنا. دعنا نرى كيف يبدو المبتدئ البسيط ، والذي يحصل على الاسم من مستودعنا:
getters: { NAME: state => { return state.name; }, }
لاحظ أن اسم Getter بالأحرف الكبيرة. هذه مجرد توصية بنمط التعليمات البرمجية. ليس من الضروري متابعته إذا لم تعجبك.
الآن بعد أن حددنا أداة getter للاسم ، أصبح من السهل جدًا الحصول على قيمة الاسم داخل المكون الخاص بنا. يتيح لك الرمز أدناه القيام بذلك.
let name = this.$store.getters.NAME;
اكتشفنا كيفية الحصول على البيانات من التخزين. الآن دعونا نرى كيف يمكننا ضبط البيانات في المستودع. سنحدد المستوطنين ، أليس كذلك؟ بالإضافة إلى ذلك ، يتم تسمية مستوطني Vuex بشكل مختلف قليلاً. نحدد طفرة لتعيين البيانات إلى حالة Vuex.
mutations: { SET_NAME: (state, payload) => { state.name = payload; }, }
ما هي الحمولة الأخرى؟ الحمولة هي البيانات المرسلة إلى طفرتنا من المكون الذي يجعل الطفرة. كيف يمكننا فعل ذلك؟ بسيط جدا:
this.$store.commit('SET_NAME', your_name);
سيغير هذا الجزء من التعليمات البرمجية حالة التطبيق ويعيّن أي قيمة مخصصة لـ your_name لخاصية الاسم داخل مستودعنا.
طفرات متزامنة
تخيل أن لدينا قائمة بالأسماء المخزنة في قاعدة بيانات على خادم بعيد. يوفر لنا الخادم نقطة نهاية تُرجع مجموعة من الأسماء التي يمكن استخدامها في Vue.js. بالطبع ، يمكننا استخدام Axios للاستعلام عن نقطة النهاية والحصول على البيانات.
let {data} = await Axios.get('https://myapiendpoint.com/api/names');
بعد ذلك ، يمكننا تمرير الصفيف الذي تم إرجاعه إلى حالة المتجر Vuex باستخدام طفرة. سهل أليس كذلك؟ لكن ليس حقًا. الطفرات متزامنة ، ولا يمكننا تشغيل عمليات غير متزامنة ، مثل مكالمات API ، داخل طفرة.
ماذا نفعل بعد ذلك؟ إنشاء إجراءات .
الإجراءات هي مثل الطفرات ، ولكن بدلاً من تغيير الحالة مباشرة ، فإنها تحدث طفرة. يبدو مربكا؟ دعونا نلقي نظرة على إعلان العمل.
actions: { SET_NAME: (context, payload) { context.commit('SET_NAME', payload); }, }
قمنا بتعريف إجراء يسمى SET_NAME يأخذ السياق والحمولة كمعلمات. يؤدي الإجراء إلى حدوث الطفرة SET_NAME ، التي تم إنشاؤها سابقًا ، مع تمرير البيانات إليها ، أي your_name .
الآن ، بدلاً من استدعاء الطفرة مباشرة ، تقوم مكوناتنا بتشغيل إجراء SET_NAME باسم جديد كبيانات على النحو التالي:
this.$store.dispatch('SET_NAME', your_name);
ثم يبدأ الإجراء التحور بالبيانات التي تم تمريرها إليه ، أي your_name .
لكن لماذا؟
قد تتساءل عن سبب الحاجة إلى إعلان إجراء إذا تمكنا ببساطة من بدء طفرات بقيمة جديدة مباشرة من مكوناتنا. كما ذكر أعلاه ، تكون الطفرات متزامنة ، ولكن لا توجد إجراءات.
في المثال أعلاه ، يتم النظر في الحالة عندما تحتاج إلى تحديث قيمة الاسم ، ولكن ليس فقط في حالتها ، ولكن أيضًا في قاعدة البيانات التي تعمل على الخادم البعيد. أنا متأكد من أن هذه هي الطريقة التي تنوي بها استخدام Vuex في مشروع حقيقي في 99 ٪ من الحالات. ألق نظرة على مقتطف الشفرة التالي:
mutations: { SET_NAME: (state, name) => { state.name = name; }, }, actions: { SET_NAME: async (context, name) => { let {data} = await Axios.post('http://myapiendpoint.com/api/name', {name: name}); if (data.status == 200) { context.commit('SET_NAME', name); } }, }
المدونة نفسها تفسر نفسها بنفسها. نستخدم Axios لإرسال الاسم إلى نقطة النهاية. إذا كان طلب POST ناجحًا ، وتم تغيير قيمة اسم الحقل بنجاح على الخادم ، فإننا نبدأ طفرة SET_ NAME لتحديث قيمة الاسم داخل حالتنا.
خذ الممارسة بألا تباشر العادات المباشرة. لهذا دائما استخدام الإجراءات.
تكوين تخزين Vuex في Vue.JS
دعونا نتعمق أكثر ونكتشف كيف يمكننا تنفيذ Vuex في تطبيق حقيقي.
الخطوة 1. تثبيت Vuex
npm install --save vuex
الخطوة 2. إنشاء مستودع Vuex
- إنشاء دليل المتجر في جذر تطبيقنا.
- قم بإنشاء ملف index.js في هذا الدليل واستخدم الكود أدناه لإنشاء مستودع جديد.
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, });
الخطوة 3. إضافة التخزين Vuex إلى تطبيق Vue.JS
1. قم باستيراد المستودع في ملف main.js:
import {store} from './store';
2. أضف مساحة التخزين إلى مثيل Vue ، كما هو موضح أدناه:
new Vue({ el: '#app', store, router, render: h => h(App), });
الآن يمكننا إضافة متغيرات الحالة ، والرسائل ، والطفرات ، والإجراءات إلى مستودع Vuex الخاص بنا.
مثال
ألق نظرة على مستودع Vuex لتطبيق قائمة مهام بسيط. "ليست مجرد قائمة مهام أخرى !!!". هاه؟ لا تقلقي. في نهاية هذه المقالة ، ستتعلم كيفية استخدام القوة الكاملة وقوة Vuex.
import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; Vue.use(Vuex); export const store = new Vuex.Store({ state: { todos: null, }, getters: { TODOS: state => { return state.todos; }, }, mutations: { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }, actions: { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }, });
قم بإضافة عنصر جديد إلى قائمة المهام
داخل المكون الخاص بك ، ابدأ في إجراء SAVE_TODO بتمرير عنصر مهام جديد إليه ، كما هو موضح في مقتطف الرمز أدناه.
let item = 'Get groceries'; this.$store.dispatch('SAVE_TODO', item);
يقوم إجراء SAVE_TODO بإجراء طلب POST إلى نقطة النهاية ، ثم يبدأ طفرة ADD_TODO ، والتي تضيف عنصر مهام إلى متغير حالة المهام .
الحصول على المهام
داخل الكتلة المركبة () للمكون الخاص بك ، ابدأ إجراء GET_TODO الثاني ، الذي يستقبل جميع عناصر المهام من نقطة النهاية ويخزنها في متغير حالة todos ، مع بدء طفرة SET_TODO:
mounted() { this.$store.dispatch('GET_TODO'); }
الوصول إلى عناصر المهام داخل المكون
للوصول إلى عنصر المهام داخل مكون ، قم بإنشاء خاصية محسوبة:
computed: { todoList() { return this.$store.getters.TODOS; }, }
داخل المكون ، يمكنك الوصول إلى الخاصية المحسوبة:
<div class="todo-item" v-for="item in todoList"></div>
باستخدام طريقة mapGetters
هناك طريقة أسهل للوصول إلى عناصر المهام داخل أحد المكونات باستخدام طريقة mapGetters التي توفرها Vuex.
import {mapGetters} from 'vuex'; computed : { ...mapGetters(['TODOS']), // }
ربما كنت قد خمنت بالفعل أنه يجب تغيير الرمز داخل القالب ، كما هو موضح في المقتطف أدناه.
<div class="todo-item" v-for="item in TODOS"></div>
لاحظ كيف استخدمنا عامل توزيع ES6 [...] داخل خصائصنا المحسوبة.
تخزين VUEX ليس فقط مصدر الدولة الحالية لتطبيقك. إنها أيضًا النقطة الوحيدة التي يجب أن تغير هذه الدولة.
هذا يتطلب شرحا قليلا. لقد تعلمنا بالفعل كيفية إنشاء إجراءات لاستلام وتثبيت عناصر المهام في مستودعنا. ماذا لو احتجنا إلى تحديث عنصر ووضع علامة عليه؟ أين نقوم بتشغيل الكود لهذا؟
على الإنترنت ، يمكنك العثور على آراء مختلفة حول هذا الأمر. كما تفتقر الوثائق إلى إرشادات واضحة بشأن ذلك.
أوصي بتخزين جميع مكالمات API داخل الإجراءات في مستودع Vuex الخاص بك. وبالتالي ، يحدث كل تغيير في الحالة فقط داخل المستودع ، مما يسهل تصحيح الأخطاء وتبسيط فهم الكود ، كما يجعل تحرير الكود أسهل.
منظمة كود
سيؤدي حفظ جميع متغيرات الحالة والرسائل والإجراءات والطفرات في ملف واحد إلى جعلها مرهقة بسرعة بمجرد بدء العمل مع التطبيقات الكبيرة. دعونا نرى كيف يمكنك تنظيم التخزين في عدة ملفات كوحدات.
إنشاء دليل جديد داخل المستودع وتسميته الوحدات النمطية . أضف ملف todos.js إلى الدليل الذي تم إنشاؤه يحتوي على الكود التالي:
const state = {}; const getters = {}; const mutations = {}; const actions = {}; export default { state, getters, mutations, actions, };
يمكننا الآن نقل متغيرات الحالة ، والرسائل ، والطفرات ، والإجراءات من ملف index.js إلى ملف todos.js . تذكر استيراد أكسيوس . كل ما نحتاجه هو إعلام Vuex بأننا أنشأنا وحدة التخزين ومكان العثور عليها. يجب أن يبدو ملف index.js المحدث على النحو التالي :
import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; import todos from './modules/todos'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, modules: { todos, }, });
سيبدو ملف todos.js كما يلي:
import Axios from 'axios'; state = { todos: null, }; getters = { TODOS: state => { return state.todos; }, }; mutations = { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }; actions = { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }; export default { state, getters, mutations, actions, };
الملخص
- يتم تخزين حالة التطبيق ككائن JSON واحد كبير.
- يتم استخدام Getters للوصول إلى القيم المخزنة في المتجر.
- تحدث الطفرات حالتك. يجب أن نتذكر أن الطفرات متزامنة.
- يجب تنفيذ جميع العمليات غير المتزامنة ضمن الإجراءات . الإجراءات تغير الحالة وتبدأ الطفرات.
- اجعلها قاعدة لبدء الطفرات بشكل حصري من خلال العمل .
- يمكن استخدام الوحدات لتنظيم التخزين الخاص بك في العديد من الملفات الصغيرة.
يجعل Vuex العمل مع Vue أسهل وأكثر متعة. إذا كنت مبتدئًا ، فقد تكون هناك مواقف يصعب عليك فيها تحديد ما إذا كنت تريد استخدام Vuex في مناطق معينة من تطبيقك أم لا. اتبع غريزتك. ستصل بسرعة عالية بسرعة كبيرة.