15. المشروع [vuejs-13]: تحديث مكون، باستخدام جلسة عمل
يعتمد مشروع [vuejs-13] على مشروع [vuejs-12] من خلال إدخال التغيير التالي: يتم تعريف المصفوفة التي يعرضها جدول HTML في كائن [session] معروف لجميع المكونات. وبالتالي، فهذه طريقة لتبادل المعلومات بين المكونات. وقد استلهم هذا المفهوم مباشرة من مفهوم "جلسة الويب". ونحن نستخدم طريقة المكون الإضافي (plugin) لإتاحة هذا الكائن المشترك في سمة [Vue.$session].
هيكل دليل المشروع كما يلي:

15.1. كائن [session]
يتم تعريف كائن [session] المشترك بين جميع المكونات في البرنامج النصي [./session.js]:
const session = {
// liste des simulations
get lignes() {
return this._lignes;
},
// génération de la liste des simulations
generateLignes() {
this._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 }
]
},
// suppression ligne n° index
deleteLigne(index) {
this._lignes.splice(index, 1);
}
}
// export de l'objet [session]
export default session;
15.2. المكوّن الإضافي [./plugins/pluginSession]
النص البرمجي [pluginSession] هو كما يلي:
export default {
install(Vue, session) {
// ajoute une propriété [$session] à la classe vue
Object.defineProperty(Vue.prototype, '$session', {
// lorsque Vue.$session est référencé, on rend le 2ième paramètre [session] de la méthode [install]
get: () => session,
})
}
}
- السطر 4: سيكون الكائن المشترك [session] متاحًا في الخاصية [$session] لجميع المكونات؛
15.3. البرنامج النصي الرئيسي [main.js]
البرنامج النصي الرئيسي [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';
import pluginSession from './plugins/pluginSession'
Vue.use(pluginSession, session)
// configuration
Vue.config.productionTip = false
// instanciation projet [App]
new Vue({
name: "app",
render: h => h(App),
}).$mount('#app')
- الأسطر 14–16: تم دمج المكون الإضافي [pluginSession] في إطار عمل [Vue.js]؛
- بعد السطر 16، تصبح السمة [$session] متاحة لجميع المكونات؛
15.4. العرض الرئيسي [App]
أصبح العرض [App] الآن كما يلي:
<template>
<div class="container">
<b-card>
<!-- message -->
<b-alert show variant="success" align="center">
<h4>[vuejs-13] : mise à jour d'un composant, partage des données avec une session</h4>
</b-alert>
<!-- table HTML -->
<Table @updateTable="updateTable" :key="versionTable"/>
</b-card>
</div>
</template>
<script>
import Table from "./components/Table";
export default {
// nom
name: "app",
// composants
components: {
Table
},
// état interne
data() {
return {
// version table
versionTable: 1
};
},
// méthodes
methods: {
updateTable() {
// eslint-disable-next-line
console.log("App updateTable");
// incrément version table
this.versionTable++;
}
}
};
</script>
تعليقات
- لم تعد طريقة العرض [App] تدير الجدول الذي يعرضه مكون [Table] في السطر 9؛
- السطر 9: يصدر مكون [Table] حدث [updateTable]، الذي يطلب إعادة عرض مكون [Table]. إحدى طرق القيام بذلك هي استخدام السمة [:key]. نمنح هذه السمة قيمة قابلة للتغيير. في كل مرة يتم تعديلها، يتم إعادة عرض مكون [Table]؛
- السطر 9: قيمة السمة [:key] هي السمة [versionTable] في السطر 27. طريقة [updateTable] (الأسطر 33–38) مسؤولة عن إعادة إنشاء مكون [Table] من السطر 9. للقيام بذلك، تقوم الطريقة بزيادة قيمة السمة [:key] لمكون [Table] في السطر 37. ثم يتم إعادة إنشاء مكون [Table] تلقائيًا؛
15.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.$session.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.$session.deleteLigne(index);
// on demande au composant parent de mettre à jour la vue
this.$emit("updateTable");
},
// 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.$session.generateLignes();
// on demande au composant parent de mettre à jour la vue
this.$emit("updateTable");
}
}
};
</script>
تعليقات:
- لم تعد السمة [rows] (الأسطر 4 و12 و17) معلمة يحددها المكون الأصلي، بل أصبحت سمة محسوبة للمكون [Table] (الأسطر 30-32). وبالتالي، فإن [rows] هي المصفوفة [$session.rows] (السطر 31)؛
- الأسطر 49-56: تزيل طريقة [deleteRow] صفًا من المصفوفة [$session.rows]. بشكل افتراضي، لا يغير هذا الحذف عرض جدول HTML. ويرجع ذلك إلى أن عناصر [$session] غير تفاعلية: لا تنعكس التغييرات التي تطرأ عليها في المكونات التي تستخدمها. لهذا السبب، يطلب مكون [Table] من المكون الأصلي إعادة إنشائه باستخدام حدث [updateTable] (السطر 55). وقد رأينا أن المكون الأصلي سيقوم بعد ذلك بزيادة سمة [:key] لمكون [Table] لإجباره على إعادة إنشائه؛
- الأسطر 58–65: تطلب طريقة [reloadList] من كائن [$session] إعادة إنشاء مصفوفة [$session.rows]. وللسبب نفسه المذكور سابقًا، لا يؤدي هذا التعديل على [$session.list]، بشكل افتراضي، إلى تغيير عرض جدول HTML. لهذا السبب، يطلب مكون [Table] من المكون الأصلي إعادة إنشائه باستخدام حدث [updateTable] (السطر 64).
15.6. تشغيل المشروع

نحصل على نفس النتائج كما في مشروع [vuejs-12].