6. المشروع [vuejs-04]: التوجيهات [v-model، v-bind]، الخصائص المحسوبة، نموذج الإدخال
هيكل دليل مشروع [vuejs-04] كما يلي:

6.1. البرنامج النصي الرئيسي [main.js]
وهو نفس البرنامج النصي في المثال السابق.
6.2. المكون الرئيسي [App]
فيما يلي كود [App.vue]:
<template>
<b-container>
<b-card>
<!-- message de présentation -->
<b-row>
<b-col cols="8">
<b-alert show variant="success" align="center">
<h4>[vuejs-04] : directives [v-model, v-bind], attributs calculés, formulaire de saisie</h4>
</b-alert>
</b-col>
</b-row>
<Form />
</b-card>
</b-container>
</template>
<script>
import Form from "./components/Form.vue";
export default {
name: "app",
components: {
Form
}
};
</script>
يستخدم المكون [App.vue] المكون الجديد [Form] (الأسطر 12 و19 و24).
6.3. مكون [Form]
فيما يلي كود مكون [Form]:
<template>
<div>
<!-- form -->
<b-form>
<!-- form elements -->
<b-row>
<b-col cols="4">
<b-card bg-variant="light">
<b-form-group label="Nombre d'enfants à charge" label-for="enfants">
<b-input type="text"
id="enfants"
placeholder="Indiquez votre nombre d'enfants"
v-model="enfants"
v-bind:state="enfantsValide" />
<b-form-invalid-feedback :state="enfantsValide">Vous devez saisir un nombre positif ou nul</b-form-invalid-feedback>
</b-form-group>
<!-- button -->
<b-button variant="primary" :disabled="formInvalide" @click="doSomething">Valider</b-button>
</b-card>
</b-col>
</b-row>
</b-form>
<b-row class="mt-3">
<b-col cols="4">
<b-alert show variant="warning" align="center">
<h4>enfants= {{enfants}}</h4>
</b-alert>
</b-col>
</b-row>
</div>
</template>
<!-- script -->
<script>
export default {
// nom
name: "Form",
// attributs statiques du composant
data() {
return {
// nbre d'enfants
enfants: ""
};
},
// attributs calculés
computed: {
// attribut [formInvalide]
formInvalide() {
return !this.enfantsValide;
},
// attribut [enfantsInvalide]
enfantsValide() {
return Boolean(this.enfants.match(/^\s*\d+\s*$/));
}
},
// méthodes
methods: {
doSomething() {
// le nbre d'enfants est connu lorsque la validation a lieu
alert("Nombre d'enfants : " + this.enfants);
}
}
};
</script>
الناتج المرئي


تعليقات
- الأسطر 4–32: تُدرج علامة <b-form> نموذج Bootstrap؛
- السطر 6: العلامة <b-row> تضيف صفًا في النموذج؛
- السطر 7: العلامة <b-col cols=’4’> تضيف عمودًا يمتد على 4 أعمدة Bootstrap؛
- السطر 8: العلامة <b-card> [6] تضيف بطاقة Bootstrap، وهي منطقة محاطة بإطار؛
- السطر 9: تضيف علامة <b-form-group> مجموعة من عناصر النموذج المرتبطة ببعضها البعض. هنا، يتم ربط تسمية (السمة [label]) [1] بحقل إدخال (السمة [label-for]). قيمة [label-for] هي قيمة حقل [id] (السطر 12) لحقل الإدخال؛
- الأسطر 10-14: تقدم علامة <b-input> [2] حقل إدخال:
- السطر 10: تشير [type='text'] إلى أنه يمكن كتابة نص في حقل الإدخال. كان بإمكاننا كتابة [type='number'] مع قيود [min='val1' max='val2' step='val3'] نظرًا لأننا نتوقع عددًا من العناصر التابعة. استخدمنا [type='text'] لتوضيح كيفية التحقق من صحة الإدخال؛
- السطر 12: تحدد السمة [placeholder] [3] الرسالة المعروضة في حقل الإدخال حتى يقوم المستخدم بإدخال شيء ما؛
- السطر 13: تربط توجيهات [v-model] القيمة المدخلة بشكل ثنائي الاتجاه بالسمة [children]، السطر 42، للمكون:
- عندما تتغير القيمة المدخلة، تتغير أيضًا قيمة السمة [children]؛
- عندما تتغير قيمة السمة [children]، تتغير القيمة المدخلة أيضًا، أي يتغير محتوى [2]؛
- النقطة المهمة التي يجب فهمها هي أنه، بفضل الآلية الموضحة أعلاه، عندما ينقر المستخدم على زر [التحقق من الصحة] [5]، تتخذ السمة [children] في السطر 42 القيمة التي تم إدخالها في [2]؛
- السطر 14: تُنشئ توجيهة [v-bind] ارتباطًا بين سمة من سمات علامة <b-input> — في هذه الحالة، السمة [state] — وسمة مكون — في هذه الحالة، [enfantsValide] في السطر 53. وتتميز السمة [enfantsValide] بأنها وظيفة تُرجع قيمة السمة. ويُطلق على هذا النوع من السمات اسم السمة المحسوبة. توجد السمات المحسوبة في الخاصية [computed]، السطر 47، للمكون. تُستخدم السمات المحسوبة بنفس طريقة استخدام السمات الثابتة للخاصية [data]: في السطر 14، لا نكتب [v-bind:state=’enfantsValide()’] بل [v-bind:state=’enfantsValide’]، بدون الأقواس. لذلك، عند قراءة [template]، من المستحيل التمييز بين السمة المحسوبة والسمة الثابتة. للقيام بذلك، يجب فحص كود البرنامج النصي للمكون؛
- السطر 14: تحدد السمة [state] حالة صحة/عدم صحة القيمة المدخلة: إذا عادت [enfantsValide] بقيمة [true]، تُعتبر القيمة المدخلة صحيحة؛ وإلا، تُعتبر غير صحيحة. تُظهر لقطة الشاشة أعلاه مكون [b-input] عندما تعود الدالة [enfantsValide] بقيمة [false]؛
- السطر 15: تعرض علامة <b-form-invalid-feedback> [4] رسالة عندما يكون الإدخال في [2] غير صالح. سمة [:state='childrenValid'] الخاصة بها مطابقة للسمة [v-bind:state='childrenValid'] في السطر 14. يمكن حذف توجيه [v-bind]، ولكن يجب الاحتفاظ بالرمز [:]. وبالتالي، يتم عرض رسالة الخطأ عندما تكون السمة [childrenValid] هي [false]؛
- السطر 16: نهاية مجموعة عناصر <b-group>؛
- السطر 18: الزر [5] الذي سيتحقق من صحة الإدخال:
- سيكون لونه أزرق [variant='primary'];
- [:disabled="formInvalide"]: تعمل السمة [disabled] على تمكين الزر أو تعطيله. هذه السمة مرتبطة (v-bind) بالسمة المحسوبة [formInvalide] في السطر 49؛
- [@click="doSomething"]: عندما ينقر المستخدم على الزر، سيتم تنفيذ الأسلوب [doSomething] في السطر 59؛
- الأسطر 19-22: إغلاق العلامات المفتوحة المختلفة؛
- الأسطر 23–29: سطر جديد في [template]. [class=’mt-3’] تعني [هامش (m) علوي (t) يساوي 3 فواصل]. [spacer] هي وحدة تباعد في Bootstrap. تخلق هذه الفئة التباعد [8] في لقطة الشاشة أعلاه. بدون هذه الفئة، تكون المنطقة [7] متساوية مع المناطق [1-6]؛
- السطر 24: عمود يمتد على 4 أعمدة Bootstrap؛
- الأسطر 25-27: تنبيه [warning] يعرض قيمة السمة الثابتة [children] (السطر 42). نظرًا لأن هذه السمة لها ارتباط ثنائي الاتجاه مع حقل الإدخال، فبمجرد أن يقوم المستخدم بتعديلها، تتغير أيضًا القيمة المعروضة في التنبيه؛
- الأسطر 34–65: كود JavaScript الخاص بالمكون؛
- السطر 42: السمة الثابتة الوحيدة للمكون؛
- الأسطر 47-56: السمات المحسوبة للمكون؛
- الأسطر 53-55: يُعتبر الإدخال صالحًا إذا كان عددًا صحيحًا موجبًا، ويُسمح بوجود مسافات قبله أو بعده؛
- الأسطر 49-51: يعتبر النموذج صالحًا إذا كان عدد الأطفال المدخلين صالحًا. بشكل عام، يحتوي النموذج على حقول متعددة ويعتبر صالحًا إذا كانت جميعها صالحة؛
- الأسطر 58–63: طرق المكون التي تستجيب لأحداثه. هنا، يوجد حدث واحد فقط: النقر [click] على الزر. نحن نعرض ببساطة القيمة التي تم إدخالها لإثبات أننا نستطيع الوصول إليها؛
6.4. تشغيل المشروع
نقوم بتعديل ملف [package.json] وتشغيل المشروع:
