Skip to content

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

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

Image

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

Image

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

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


// plugin Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
 
// la session est un store Vuex
const session = new Vuex.Store({
  state: {
    // le tableau des simulations
    lignes: []
  },
  mutations: {
    // génération de la liste des simulations
    generateLignes(state) {
      // eslint-disable-next-line no-console
      console.log("mutation generateLignes");
      // on initialise [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);
    },
    // suppression ligne n° index
    deleteLigne(state, index) {
      // eslint-disable-next-line no-console
      console.log("mutation deleteLigne");
      // on supprime la ligne n° [index]
      state.lignes.splice(index, 1);
    }
  }
});
// export de l'objet [session]
export default session;

تعليقات

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

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

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

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


// imports
import Vue from 'vue'
import App from './App.vue'
 
// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);
 
// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
 
// session
import session from './session';
 
// configuration
Vue.config.productionTip = false
 
// instanciation projet [App]
new Vue({
  name: "app",
  // utilisation store de Vuex
  store: session,
  render: h => h(App),
}).$mount('#app')

تعليقات

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

17.4. العرض الرئيسي [App]

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


<template>
  <div class="container">
    <b-card>
      <!-- message -->
      <b-alert show variant="success" align="center">
        <h4>[vuejs-14] : utilisation du plugin [Vuex]</h4>
      </b-alert>
      <!-- table HTML -->
      <Table />
    </b-card>
  </div>
</template>
 
<script>
import Table from "./components/Table";
export default {
  // nom
  name: "app",
  // composants
  components: {
    Table
  },
  // cycle de vie
  created() {
    // génération du tableau des simulations
    this.$store.commit("generateLignes");
  }
};
</script>

تعليقات

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

// instanciation vue [App]
new Vue({
  name: "app",
  // utilisation store de Vuex
  store: session,
  render: h => h(App),
}).$mount('#app')

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

17.5. مكون [Table]

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


<template>
  <div>
    <!-- empty list -->
    <template v-if="lignes.length==0">
      <b-alert show variant="warning">
        <h4>Votre liste de simulations est vide</h4>
      </b-alert>
      <!-- reload button-->
      <b-button variant="primary" @click="rechargerListe">Recharger la liste</b-button>
    </template>
    <!-- non-empty list-->
    <template v-if="lignes.length!=0">
      <b-alert show variant="primary" v-if="lignes.length==0">
        <h4>Liste de vos simulations</h4>
      </b-alert>
      <!-- simulation table -->
      <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 {
  // état calculé
  computed: {
    lignes() {
      return this.$store.state.lignes;
    }
  },
  // état interne
  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" }
      ]
    };
  },
  // méthodes
  methods: {
    supprimerLigne(index) {
      // eslint-disable-next-line
      console.log("Table supprimerLigne", index);
      // on supprime la ligne
      this.$store.commit("deleteLigne", index);
    },
    // rechargement de la liste affichée
    rechargerListe() {
      // eslint-disable-next-line
      console.log("Table rechargerListe");
      // on régènère la liste des simulations
      this.$store.commit("generateLignes");
    }
  }
};
</script>

تعليقات

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

17.6. الخلاصة

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