Skip to content

17. المشروع [vuejs-15]: استخدام المكون الإضافي [Vuex]

يستند المشروع [vuejs-15] إلى المشروع [vuejs-14] باستخدام كائن تفاعلي [session] تم إنشاؤه بواسطة [Vuex]. وهيكل المشروع هو كما يلي:

Image

17.1. تثبيت التبعية [vuex]

Image

17.2. البرنامج النصي [./session.js]

يصبح الكائن [session] كما يلي:


// مكوّن إضافي Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);

// الجلسة هي مخزن Vuex
const session = new Vuex.Store({
  state: {
    // جدول عمليات المحاكاة
    lignes: []
  },
  mutations: {
    // إنشاء قائمة عمليات المحاكاة
    generateLignes(state) {
      // eslint-disable-next-line no-console
      console.log("mutation generateLignes");
      // يتم تهيئة [state.lignes]
      state.lignes =
        [
          { id: 3, marié: "oui", enfants: 2, salaire: 35000, impôt: 1200 },
          { id: 5, marié: "non", enfants: 2, salaire: 35000, impôt: 1900 },
          { id: 7, marié: "non", enfants: 0, salaire: 30000, impôt: 2000 }
        ];
      // eslint-disable-next-line no-console
      console.log(state.lignes);
    },
    // حذف السطر رقم الفهرس
    deleteLigne(state, index) {
      // eslint-disable-next-line no-console
      console.log("mutation deleteLigne");
      // يتم حذف السطر رقم [index]
      state.lignes.splice(index, 1);
    }
  }
});
// تصدير الكائن [session]
export default session;

تعليقات

  • الأسطر 2-4: يتم دمج المكون الإضافي [Vuex] في إطار العمل [Vue]؛
  • السطر 7: تصبح الجلسة كائنًا من النوع [Vuex.Store]؛
  • الأسطر 8-11: تحتوي الخاصية [state] على الحالة المشتركة للتطبيق [Vue]. وستكون هذه الخاصية متاحة لجميع مكونات التطبيق. هنا نشارك مصفوفة المحاكاة [lignes] (السطر 10)؛
  • الأسطر 12-35: تجمع الخاصية [mutations] الطرق التي تُعدّل محتوى الكائن [state]؛
  • الأسطر 14-26: الخاصية [generateLignes] هي دالة تولد قيمة أولية للخاصية [state.lignes]. وهي تقبل هنا [state] كمعلمة. الأسطر 18-23: يتم تهيئة الخاصية [state.lignes]؛
  • الأسطر 28-35: الخاصية [deleteLigne] هي دالة تحذف سطرًا من المصفوفة [state.lignes]. ومعلماتها هي:
    • [state] التي تمثل الكائن المذكور في الأسطر 8-11؛
    • [index] وهو رقم السطر المراد حذفه؛
  • تقبل دوال الخاصية [mutations] دائمًا كمعلمة أولى كائنًا يمثل الخاصية [state] للسطر 8. يتم توفير المعلمات التالية بواسطة الكود الذي يستدعي عملية التغيير؛
  • السطر 37: يتم تصدير الكائن [session].

على عكس المشروع السابق [vuejs-13 لن يكون لدينا هنا مكون إضافي لجعل الجلسة متاحة للمكونات في سمة [Vue.$session].

17.3. البرنامج النصي الرئيسي [./main.js]

يتطور البرنامج النصي الرئيسي على النحو التالي:


// عمليات الاستيراد
import Vue from 'vue'
import App from './App.vue'

// المكونات الإضافية
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// Bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// جلسة
import session from './session';

// التكوين
Vue.config.productionTip = false

// إنشاء مثيل للمشروع [App]
new Vue({
  name: "app",
  // استخدام مخزن Vuex
  store: session,
  render: h => h(App),
}).$mount('#التطبيق')

تعليقات

  • السطر 14: يتم استيراد الجلسة؛
  • السطر 23: يتم تمريرها إلى العرض الرئيسي في سمة تُسمى [store] (وهذا أمر إلزامي). وبفضل المكون الإضافي [Vuex]، تصبح هذه السمة متاحة لجميع المكونات في سمة [Vue.$store]. لذلك نحن في تكوين مشابه جدًّا لتلك الموجودة في المشروع السابق: فحيث كان يتم الوصول إلى الجلسة في أحد المكونات عبر الترميز [this.$session]، سيصبح الوصول إليها الآن عبر الترميز [this.$store]؛

17.4. الطريقة الرئيسية [App]

تتطور الواجهة الرئيسية [App] على النحو التالي:


<template>
  <div class="container">
    <b-card>
      <!-- رسالة -->
      <b-alert show variant="success" align="center">
        <h4>[vuejs-14] : utilisation du plugin [Vuex]</h4>
      </b-alert>
      <!-- جدول HTML -->
      <Table />
    </b-card>
  </div>
</template>

<script>
import Table from "./components/Table";
export default {
  // الاسم
  name: "app",
  // المكونات
  components: {
    Table
  },
  // دورة الحياة
  created() {
    // إنشاء جدول المحاكاة
    this.$store.commit("generateLignes");
  }
};
</script>

تعليقات

  • السطر 9: تستخدم طريقة العرض [App] المكون [Table] ولكنها لم تعد تتلقى أحداثًا منه، وذلك بفضل كون مخزن البيانات [Vuex] تفاعليًّا؛
  • الأسطر 24-27: يتم تنفيذ الأسلوب [created] مباشرة بعد إنشاء المكون [App]. وفي هذا الأسلوب، يتم تنفيذ العملية المسماة [generateLignes] التي تولد قيمة أولية لمصفوفة المحاكاة. تجدر الإشارة إلى الصيغة الخاصة للأمر. ونذكر أن الترميز [this.$store] يشير إلى الخاصية [store] للعرض الذي تم إنشاء مثيل له في [main.js]:

// إنشاء مثيل للطريقة [App]
new Vue({
  name: "app",
  // استخدام مخزن Vuex
  store: session,
  render: h => h(App),
}).$mount('#app')

وبالتالي، فإن الترميز [this.$store] يشير إلى الكائن [session]. ثم نكتب [this.$store.commit("generateLignes")] لتنفيذ التغيير المسمى [generateLignes]. هذا التغيير هو دالة؛

17.5. المكون [Table]

يتطور المكون [Table] على النحو التالي:


<template>
  <div>
    <!-- قائمة فارغة -->
    <template v-if="lignes.length==0">
      <b-alert show variant="warning">
        <h4>Votre liste de simulations est vide</h4>
      </b-alert>
      <!-- زر إعادة التحميل-->
      <b-button variant="primary" @click="rechargerListe">Recharger la liste</b-button>
    </template>
    <!-- قائمة غير فارغة-->
    <template v-if="lignes.length!=0">
      <b-alert show variant="primary" v-if="lignes.length==0">
        <h4>Liste de vos simulations</h4>
      </b-alert>
      <!-- جدول المحاكاة -->
      <b-table striped hover responsive :items="lignes" :fields="fields">
        <template v-slot:cell(action)="row">
          <b-button variant="link" @click="supprimerLigne(row.index)">Supprimer</b-button>
        </template>
      </b-table>
    </template>
  </div>
</template>

<script>
export default {
  // الحالة المحسوبة
  computed: {
    lignes() {
      return this.$store.state.lignes;
    }
  },
  // الحالة الداخلية
  data() {
    return {
      fields: [
        { label: "#", key: "id" },
        { label: "Marié", key: "marié" },
        { label: "Nombre d'enfants", key: "enfants" },
        { label: "Salaire", key: "salaire" },
        { label: "Impôt", key: "impôt" },
        { label: "", key: "action" }
      ]
    };
  },
  // الأساليب
  methods: {
    supprimerLigne(index) {
      // eslint-disable-next-line
      console.log("Table supprimerLigne", index);
      // يتم حذف السطر
      this.$store.commit("deleteLigne", index);
    },
    // إعادة تحميل القائمة المعروضة
    rechargerListe() {
      // eslint-disable-next-line
      console.log("Table rechargerListe");
      // إعادة إنشاء قائمة عمليات المحاكاة
      this.$store.commit("generateLignes");
    }
  }
};
</script>

تعليقات

  • لا يتغير المكون [template] في الأسطر 1-24؛
  • السطور 30-32: تستخدم الخاصية المحسوبة [lignes] الآن [store] من [Vuex]؛
  • الأسطر 49-54: لحذف سطر من الجدول HTML، يتم استخدام التغيير [deleteLigne] من [store] لـ [Vuex]. يتم تمرير الرقم [index] الخاص بالسطر المراد حذفه (السطر 53) كمعلمة؛
  • السطور 56-61: لإعادة تحميل الجدول HTML بقائمة جديدة، يتم استخدام التحويل [generateLignes] من [store] إلى [Vuex]؛

17.6. Conclusion

تتشابه سمات [Vue.$session] الخاصة بالمشروع [vuejs-13] وسمات [Vue.$store] الخاصة بالمشروع [vuejs-15] بشكل كبير. فهي تهدف إلى تحقيق نفس الهدف: مشاركة المعلومات بين طرق العرض. وتتمثل ميزة الكائن [store] في أنه تفاعلي، في حين أن الكائن [session] ليس كذلك. لكن المشروع [vuejs-14] أظهر أنه من السهل جعل الكائن [session] تفاعليًا عن طريق نسخه في الخصائص التفاعلية للعروض.