الشروع في العمل مع Axios في Nuxt

نشرت: 2022-03-10
ملخص سريع ↬ في هذا البرنامج التعليمي ، سوف نتعلم كيفية تقديم طلب في تطبيقات Nuxt.js الخاصة بنا باستخدام وحدة Axios. سنتعلم أيضًا كيفية استخدام طرق ayncData fetch البيانات لجلب البيانات على جانب الخادم باستخدام Axios والاختلافات بين الطريقتين. أخيرًا ، سوف نتعلم كيفية إضافة المصادقة إلى تطبيقنا باستخدام وحدة المصادقة.

يوفر Nuxt.js وحدة Axios لسهولة التكامل مع تطبيقك. Axios هو عميل HTTP قائم على الوعود ويعمل في المتصفح وبيئة Node.js أو ، بعبارات أبسط ، هو أداة لتقديم الطلبات (مثل استدعاءات واجهة برمجة التطبيقات) في التطبيقات من جانب العميل وبيئة Node.js.

في هذا البرنامج التعليمي ، سنتعلم كيفية استخدام وحدة Axios وكيفية تقديم طلب على جانب الخادم باستخدام asyncData and fetch. تقدم هاتان الطريقتان طلبًا من جانب الخادم ولكن لديهما بعض الاختلافات التي سنغطيها أيضًا. أخيرًا ، سنتعلم كيفية إجراء المصادقة وتأمين الصفحات / المسارات باستخدام وحدة المصادقة والبرمجيات الوسيطة للمصادقة.

تتطلب هذه المقالة معرفة أساسية بـ Nuxtjs و Vuejs لأننا سنبني فوق ذلك. بالنسبة لأولئك الذين ليس لديهم خبرة مع Vuejs ، أوصيك بالبدء من وثائقهم الرسمية وصفحة Nuxt الرسمية قبل متابعة هذه المقالة.

ما هي وحدة المحاور Nuxt.js؟

وبحسب التوثيق الرسمي ،

"إنه تكامل آمن وسهل مع Axios مع Nuxt.js."

فيما يلي بعض ميزاته:

  1. قم بتعيين عنوان URL الأساسي تلقائيًا من جانب العميل ومن جانب الخادم.
  2. رؤوس طلبات الوكيل في SSR (مفيدة للمصادقة).
  3. طلبات نمط الجلب.
  4. متكامل مع Nuxt.js Progressbar أثناء تقديم الطلبات.

لاستخدام وحدة axios في تطبيقك ، سيتعين عليك أولاً تثبيتها باستخدام إما npm أو yarn .

غزل

 yarn add @nuxtjs/axios

NPM

 npm install @nuxtjs/axios

أضفه إلى ملف nuxt.config.js الخاص بك:

 modules: [ '@nuxtjs/axios', ], axios: { // extra config eg // BaseURL: 'https://link-to-API' }

تقبل مصفوفة modules قائمة بوحدات Nuxt.js مثل dotenv و auth وفي هذه الحالة Axios. ما فعلناه هو إبلاغ تطبيقنا بأننا سنستخدم وحدة Axios ، والتي نشير إليها باستخدام @nuxtjs/axios . ثم يتبع ذلك خاصية axios التي تعد كائنًا من التكوينات مثل baseURL لكل من جانب العميل وجانب الخادم.

الآن ، يمكنك الوصول إلى Axios من أي مكان في تطبيقك عن طريق استدعاء this.$axios.method أو this.$axios.$method . أين يمكن get الطريقة أو post أو delete .

المزيد بعد القفز! أكمل القراءة أدناه ↓

قم بعمل طلبك الأول باستخدام أكسيوس

في هذا البرنامج التعليمي ، قمت بتجميع تطبيق بسيط على Github. يحتوي المستودع على مجلدين ، البداية والنهاية ، ويحتوي مجلد البدء على كل ما تحتاجه للوصول إلى البرنامج التعليمي مباشرة. يحتوي مجلد النهاية على نسخة مكتملة مما سنبنيه.

بعد استنساخ الريبو وفتح مجلد start ، سنحتاج إلى تثبيت جميع الحزم الخاصة بنا في ملف package.json ، لذا افتح Terminal وقم بتشغيل الأمر التالي:

 npm install

بمجرد الانتهاء من ذلك ، يمكننا بدء تطبيقنا باستخدام الأمر npm run dev . هذا ما يجب أن تراه عندما تذهب إلى localhost:3000 .

صفحة بها رأس تحتوي على شعار وروابط تنقل.
الصفحة المقصودة لتطبيقنا. (معاينة كبيرة)

الشيء التالي الذي يتعين علينا القيام به هو إنشاء ملف .env في المجلد الجذر لتطبيقنا وإضافة عنوان URL الخاص بواجهة برمجة التطبيقات إليه. في هذا البرنامج التعليمي ، سنستخدم نموذجًا لواجهة برمجة تطبيقات تم إنشاؤها لجمع التقارير من المستخدمين.

 API_URL=https://ireporter-endpoint.herokuapp.com/api/v2/

بهذه الطريقة ، لا يتعين علينا ترميز API الخاص بنا في تطبيقنا وهو أمر مفيد للعمل مع اثنين من واجهات برمجة التطبيقات (التطوير والإنتاج).

ستكون الخطوة التالية هي فتح ملف nuxt.config.js بنا وإضافة المتغير البيئي إلى تكوين axios الذي أضفناه أعلاه.

 /* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options baseURL: process.env.API_URL, },

هنا ، نطلب من baseURL استخدام عنوان URL الأساسي هذا لكل من طلبات جانب العميل والخادم كلما استخدمنا وحدة Axios هذه.

الآن ، لجلب قائمة التقارير ، دعونا نفتح ملف index.vue ونضيف الطريقة التالية إلى قسم البرنامج النصي.

 async getIncidents() { let res = await this.$store.dispatch("getIncidents"); this.incidents = res.data.data.incidents; }

ما فعلناه هو إنشاء دالة غير متزامنة نسميها getIncidents() ويمكننا معرفة ما تفعله من الاسم - إنها تجلب قائمة بالحوادث باستخدام طريقة إجراء متجر Vuex this.$store.dispatch . نقوم بتعيين الاستجابة من هذا الإجراء إلى خاصية الحوادث الخاصة بنا حتى نتمكن من الاستفادة منها في المكون.

نريد استدعاء طريقة getIncidents() كلما زاد المكون. يمكننا القيام بذلك باستخدام الخطاف mounted .

 mounted() { this.getIncidents() }

تم mounted() عبارة عن رابط لدورة الحياة يتم استدعاؤه عند تركيب المكون. سيؤدي ذلك إلى حدوث استدعاء لواجهة برمجة التطبيقات عند تحميل المكون. الآن ، دعنا ننتقل إلى ملف index.js بنا في متجرنا وننشئ هذا الإجراء حيث سنقوم بطلب Axios من.

 export const actions = { async getIncidents() { let res = await this.$axios.get('/incidents') return res; } }

هنا ، أنشأنا الإجراء المسمى getIncidents وهو وظيفة غير متزامنة ، ثم ننتظر استجابة من الخادم ونعيد هذه الاستجابة. يتم إرسال الاستجابة من هذا الإجراء إلى طريقة getIncidents() الخاصة بنا في ملف index.vue بنا.

إذا قمنا بتحديث تطبيقنا ، فمن المفترض أن نتمكن الآن من رؤية قائمة طويلة من الحوادث المعروضة على الصفحة.

قائمة الحوادث الوهمية.
قائمة الحوادث على الصفحة المقصودة. (معاينة كبيرة)

لقد قدمنا ​​طلبنا الأول باستخدام Axios ولكننا لن نتوقف عند هذا الحد ، سنقوم بتجربة بيانات غير متزامنة fetch لمعرفة الاختلافات بينها واستخدام asyncData .

AsyncData

تقوم AsyncData بجلب البيانات من جانب الخادم ويتم استدعاؤها قبل تحميل مكون الصفحة. ليس لديه حق الوصول إلى this لأنه تم استدعاؤه قبل إنشاء بيانات مكون الصفحة. this متاح فقط بعد استدعاء الخطاف الذي تم created لذلك يقوم Nuxt.js تلقائيًا بدمج البيانات التي تم إرجاعها في بيانات المكون.

يعد استخدام asyncData محركات البحث لأنه يجلب محتوى موقعك على جانب الخادم ويساعد أيضًا في تحميل المحتوى بشكل أسرع. لاحظ أنه لا يمكن استخدام طريقة asyncData إلا في مجلد صفحات التطبيق الخاص بك لأنها لن تعمل في مجلد المكونات. هذا لأنه يتم استدعاء خطاف asyncData قبل إنشاء المكون الخاص بك.

صورة توضح دورة حياة Nuxt.
صورة من مدونة Nuxt. (معاينة كبيرة)

دعونا نضيف بيانات غير متزامنة إلى ملف asyncData index.vue بنا ونلاحظ مدى سرعة تحميل بيانات الحوادث لدينا. أضف الكود التالي بعد خاصية المكونات الخاصة بنا ودعنا نتخلص من الخطاف المثبت لدينا.

 async asyncData({ $axios }) { let { data } = await $axios.get("/incidents"); return { incidents: data.data.incidents }; }, // mounted() { // this.getIncidents(); // },

هنا ، يقبل التابع asyncData خاصية من السياق $axios . نستخدم هذه الخاصية لجلب قائمة الحوادث ثم يتم إرجاع القيمة. يتم حقن هذه القيمة تلقائيًا في مكوننا. الآن ، يمكنك ملاحظة مدى سرعة تحميل المحتوى الخاص بك إذا قمت بتحديث الصفحة ولم يكن هناك أي حادث لعرضه في أي وقت .

أحضر

تُستخدم طريقة الجلب أيضًا لتقديم الطلبات من جانب الخادم. يتم استدعاؤه بعد الخطاف الذي تم إنشاؤه في دورة الحياة مما يعني أنه يمكنه الوصول إلى بيانات المكون. على عكس طريقة asyncData ، يمكن استخدام طريقة الجلب في جميع ملفات .vue واستخدامها مع متجر Vuex. هذا يعني أنه إذا كان لديك ما يلي في وظيفة البيانات الخاصة بك.

 data() { return { incidents: [], id: 5, gender: 'male' }; }

يمكنك بسهولة تعديل المعرف أو الجنس عن طريق استدعاء this.id أو this.gender .

استخدام Axios كمكوِّن إضافي

أثناء عملية التطوير مع Axios ، قد تجد أنك بحاجة إلى تكوين إضافي مثل إنشاء مثيلات ومعترضات لطلبك حتى يتمكن التطبيق الخاص بك من العمل على النحو المنشود ولحسن الحظ ، يمكننا القيام بذلك عن طريق توسيع Axios لدينا إلى مكون إضافي.

لتوسيع axios ، يجب عليك إنشاء مكون إضافي (مثل axios.js ) في مجلد plugins الخاصة بك.

 export default function ({ $axios, store, redirect }) { $axios.onError(error => { if (error.response && error.response.status === 500) { redirect('/login') } }) $axios.interceptors.response.use( response => { if (response.status === 200) { if (response.request.responseURL && response.request.responseURL.includes('login')) { store.dispatch("setUser", response); } } return response } ) }

هذا مثال على مكون إضافي كتبته لتطبيق Nuxt. هنا ، تأخذ وظيفتك في سياق كائن $axios ، store وإعادة redirect والتي سنستخدمها في تكوين المكون الإضافي. أول شيء نقوم به هو الاستماع لخطأ بالحالة 500 باستخدام $axios.onError وإعادة توجيه المستخدم إلى صفحة تسجيل الدخول.

لدينا أيضًا جهاز اعتراض يعترض كل استجابة طلب نجريها في تطبيقنا للتحقق مما إذا كانت حالة الاستجابة التي نحصل عليها هي 200 . إذا كان هذا صحيحًا ، فإننا نتابع ونتحقق من وجود response.request.responseURL وما إذا كان يتضمن تسجيل الدخول. إذا تحقق هذا من صحة ذلك ، فسنرسل هذه الاستجابة باستخدام طريقة الإرسال الخاصة بمتجرنا حيث تحورت بعد ذلك في حالتنا.

أضف هذا المكون الإضافي إلى ملف nuxt.config.js الخاص بك:

 plugins: [ '~/plugins/axios' ]

بعد القيام بذلك ، سيعترض المكون الإضافي Axios الخاص بك أي طلب تقدمه ويتحقق مما إذا كنت قد حددت حالة خاصة له.

مقدمة في وحدة المصادقة

تُستخدم وحدة المصادقة لإجراء المصادقة لتطبيق Nuxt الخاص بك ويمكن الوصول إليها من أي مكان في تطبيقك باستخدام $this.auth . وهو متاح أيضًا في fetch و asyncData و middleware و NuxtInitServer من كائن السياق كـ $auth .

يوفر context كائنات / معلمات إضافية من مكونات Nuxt إلى Vue وهو متاح في مناطق دورة حياة nuxt خاصة مثل تلك المذكورة أعلاه.

لاستخدام وحدة المصادقة في تطبيقك ، يجب عليك تثبيتها باستخدام yarn أو npm .

غزل

 yarn add @nuxtjs/auth

NPM

 npm install @nuxtjs/auth

قم بإضافته إلى ملف nuxt.config.js الخاص بك.

 modules: [ '@nuxtjs/auth' ], auth: { // Options }

تقبل خاصية المصادقة قائمة بالخصائص مثل strategies وإعادة redirect . هنا ، تقبل strategies طريقة المصادقة المفضلة لديك والتي يمكن أن تكون:

  • local
    لاسم المستخدم / البريد الإلكتروني والتدفق المستند إلى كلمة المرور.
  • facebook
    لاستخدام حسابات Facebook كوسيلة للمصادقة.
  • Github
    لمصادقة المستخدمين بحسابات جيثب.
  • Google
    لمصادقة المستخدمين بحسابات جوجل.
  • Auth0
  • جواز سفر Laravel

تقبل خاصية إعادة التوجيه كائنًا من الروابط من أجل:

  • login
    سيتم إعادة توجيه المستخدمين إلى هذا الارتباط إذا كان تسجيل الدخول مطلوبًا.
  • logout
    سيتم إعادة توجيه المستخدمين هنا إذا كان المسار الحالي محميًا بعد تسجيل الخروج.
  • home
    سيتم إعادة توجيه المستخدمين هنا بعد تسجيل الدخول.

الآن ، دعونا نضيف ما يلي إلى ملف nuxt.config.js بنا.

 /* ** Auth module configuration */ auth: { redirect: { login: '/login', logout: '/', home: '/my-reports' }, strategies: { local: { endpoints: { login: { url: "/user/login", method: "post", propertyName: "data.token", }, logout: false, user: false, }, tokenType: '', tokenName: 'x-auth', autoFetchUser: false }, }, }

يرجى ملاحظة أن طريقة auth تعمل بشكل أفضل عندما تكون هناك نقطة نهاية user مذكورة في الخيار أعلاه.

داخل كائن تكوين auth ، لدينا خيار redirect حيث قمنا بتعيين مسار تسجيل الدخول إلى /login وتوجيه الخروج إلى / والمسار الرئيسي إلى /my-reports والتي ستعمل جميعها كما هو متوقع. لدينا أيضًا خاصية tokenType والتي تمثل نوع التفويض في رأس طلب Axios الخاص بنا. تم ضبطه على Bearer بشكل افتراضي ويمكن تغييره للعمل مع API الخاص بك.

بالنسبة لواجهة برمجة التطبيقات (API) الخاصة بنا ، لا يوجد نوع رمز مميز ولهذا السبب سنتركه كسلسلة فارغة. يمثل tokenName اسم التفويض (أو خاصية الرأس التي تريد إرفاق رمزك المميز بها) داخل رأسك في طلب Axios الخاص بك.

بشكل افتراضي ، يتم تعيينه على Authorization ولكن بالنسبة لواجهة برمجة التطبيقات الخاصة بنا ، فإن اسم التفويض هو x-auth . يتم استخدام خاصية autoFetchUser لتمكين المستخدم من إحضار كائن باستخدام خاصية نقطة نهاية user بعد تسجيل الدخول. هذا true افتراضيًا ولكن لا تحتوي واجهة برمجة التطبيقات الخاصة بنا على نقطة نهاية user ، لذا قمنا بتعيينها على false .

في هذا البرنامج التعليمي ، سنستخدم الإستراتيجية المحلية. في استراتيجياتنا ، لدينا الخيار المحلي مع نقاط النهاية لتسجيل الدخول والمستخدم وتسجيل الخروج ولكن في حالتنا ، سنستخدم فقط خيار *login* لأن واجهة برمجة التطبيقات التجريبية الخاصة بنا لا تحتوي على نقطة نهاية *logout* ويتم إرجاع كائن المستخدم الخاص بنا عندما *login* ناجح.

ملاحظة: لا تحتوي وحدة auth على خيار نقطة نهاية التسجيل ، وهذا يعني أننا سنقوم بالتسجيل بالطريقة التقليدية وإعادة توجيه المستخدم إلى صفحة تسجيل الدخول حيث سنجري المصادقة باستخدام this.$auth.loginWith . هذه هي الطريقة المستخدمة في مصادقة المستخدمين. يقبل "إستراتيجية" (على سبيل المثال local ) كوسيطة أولى ثم كائن لأداء هذه المصادقة مع. الق نظرة على المثال التالي.

 let data { email: '[email protected]', password: '123456' } this.$auth.loginWith('local', { data })

استخدام وحدة المصادقة

الآن بعد أن قمنا بتكوين وحدة المصادقة الخاصة بنا ، يمكننا المتابعة إلى صفحة التسجيل الخاصة بنا. إذا قمت بزيارة /register ، يجب أن ترى نموذج التسجيل.

صفحة نموذج التسجيل
صفحة التسجيل. (معاينة كبيرة)

دعونا نجعل هذا النموذج وظيفيًا عن طريق إضافة الكود التالي:

 methods: { async registerUser() { this.loading = true; let data = this.register; try { await this.$axios.post("/user/create", data); this.$router.push("/login"); this.loading = false; this.$notify({ group: "success", title: "Success!", text: "Account created successfully" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }

هنا ، لدينا وظيفة غير متزامنة تسمى registerUser مرتبطة بحدث نقرة في نموذجنا وتجعل طلب Axios ملفوفًا في كتلة try / catch لنقطة نهاية /user/create . يؤدي هذا إلى إعادة التوجيه إلى صفحة /login وإخطار المستخدم بالتسجيل الناجح. لدينا أيضًا كتلة catch تنبه المستخدم لأي خطأ إذا لم ينجح الطلب.

إذا تم التسجيل بنجاح ، فسيتم إعادة توجيهك إلى صفحة تسجيل الدخول.

صفحة نموذج تسجيل الدخول
صفحة تسجيل الدخول مع مكون الإعلام. (معاينة كبيرة)

هنا ، سنستخدم طريقة مصادقة المصادقة this.$auth.loginWith('local', loginData) وبعد ذلك سنستخدم this.$auth.setUser(userObj) لتعيين المستخدم في مثيل auth الخاص بنا.

لتشغيل صفحة تسجيل الدخول ، دعنا نضيف الكود التالي إلى ملف login.vue بنا.

 methods: { async logIn() { let data = this.login; this.loading = true; try { let res = await this.$auth.loginWith("local", { data }); this.loading = false; let user = res.data.data.user; this.$auth.setUser(user); this.$notify({ group: "success", title: "Success!", text: "Welcome!" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }

أنشأنا وظيفة غير متزامنة تسمى logIn باستخدام طريقة auth this.$auth.loginWith('local, loginData) . إذا نجحت محاولة تسجيل الدخول هذه ، فسنقوم بعد ذلك بتعيين بيانات المستخدم لمثيل المصادقة الخاص بنا باستخدام this.$auth.setUser(userInfo) وإعادة توجيه المستخدم إلى صفحة /my-report .

يمكنك الآن الحصول على بيانات المستخدم باستخدام this.$auth.user أو Vuex باستخدام this.$store.state.auth.user لكن هذا ليس كل شيء. يحتوي مثيل auth على بعض الخصائص الأخرى التي يمكنك رؤيتها إذا قمت بتسجيل الدخول أو التحقق من حالتك باستخدام أدوات Vue dev الخاصة بك.

إذا قمت بتسجيل this.$store.state.auth في وحدة التحكم ، فسترى هذا:

 { "auth": { "user": { "id": "d7a5efdf-0c29-48aa-9255-be818301d602", "email": "[email protected]", "lastName": "Xo", "firstName": "Tm", "othernames": null, "isAdmin": false, "phoneNumber": null, "username": null }, "loggedIn": true, "strategy": "local", "busy": false } }

يحتوي مثيل auth على خاصية loggedIn التي تفيد في التبديل بين الروابط المصدق عليها في قسم التنقل / الرأس في التطبيق الخاص بك. يحتوي أيضًا على طريقة إستراتيجية تحدد نوع الإستراتيجية التي يعمل بها المثيل (على سبيل المثال محلي).

الآن ، سوف نستخدم خاصية loggedIn هذه لترتيب روابط nav الخاصة بنا. قم بتحديث مكون navBar الخاص بك إلى ما يلي:

 <template> <header class="header"> <div class="logo"> <nuxt-link to="/"> <Logo /> </nuxt-link> </div> <nav class="nav"> <div class="nav__user" v-if="auth.loggedIn"> <p>{{ auth.user.email }}</p> <button class="nav__link nav__link--long"> <nuxt-link to="/report-incident">Report incident</nuxt-link> </button> <button class="nav__link nav__link--long"> <nuxt-link to="/my-reports">My Reports</nuxt-link> </button> <button class="nav__link" @click.prevent="logOut">Log out</button> </div> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/login">Login</nuxt-link> </button> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/register">Register</nuxt-link> </button> </nav> </header> </template> <script> import { mapState } from "vuex"; import Logo from "@/components/Logo"; export default { name: "nav-bar", data() { return {}; }, computed: { ...mapState(["auth"]) }, methods: { logOut() { this.$store.dispatch("logOut"); this.$router.push("/login"); } }, components: { Logo } }; </script> <style></style>

في قسم القوالب لدينا ، لدينا عدة روابط لأجزاء مختلفة من التطبيق الذي نستخدم فيه الآن auth.loggedIn لعرض الروابط المناسبة اعتمادًا على حالة المصادقة. لدينا زر تسجيل الخروج يحتوي على حدث click مرفق به وظيفة logOut() . نعرض أيضًا البريد الإلكتروني للمستخدم الذي تم الحصول عليه من خاصية المصادقة التي يتم الوصول إليها من متجر Vuex الخاص بنا باستخدام طريقة mapState التي تحدد مصادقة الدولة الخاصة بنا إلى الخاصية المحسوبة لمكون التنقل. لدينا أيضًا طريقة logout التي تستدعي تسجيل خروج إجراء logOut توجيه المستخدم إلى صفحة login .

الآن ، دعونا نمضي قدمًا ونقوم بتحديث متجرنا للحصول على إجراء logOut .

 export const actions = { // .... logOut() { this.$auth.logout(); } }

يستدعي الإجراء logOut طريقة logout المصادقة التي تمسح بيانات المستخدم ، وتحذف الرموز المميزة من localStorage loggedIn على false .

يجب ألا تكون المسارات مثل /my-reports report-incident مرئية للضيوف ولكن في هذه المرحلة في تطبيقنا ، ليس هذا هو الحال. لا يحتوي Nuxt على حارس ملاحة يمكنه حماية مساراتك ، ولكنه يحتوي على برمجية وسيطة. يمنحك حرية إنشاء البرامج الوسيطة الخاصة بك حتى تتمكن من تكوينها للعمل بالطريقة التي تريدها.

يمكن ضبطه بطريقتين:

  1. لكل طريق.
  2. عالميًا للتطبيق بأكمله في ملف nuxt.config.js الخاص بك.
 router: { middleware: ['auth'] }

تعمل برمجية auth الوسيطة هذه مع مثيل auth الخاص بك ، لذا لا تحتاج إلى إنشاء ملف auth.js في مجلد البرنامج الوسيط الخاص بك.

دعونا الآن نضيف هذه البرامج الوسيطة إلى ملفات my-reports.vue و report-incident.vue accident.vue الخاصة بنا. أضف الأسطر التالية من التعليمات البرمجية إلى قسم البرنامج النصي لكل ملف.

 middleware: 'auth'

الآن ، سيتحقق تطبيقنا مما إذا كان المستخدم الذي يحاول الوصول إلى هذه المسارات لديه قيمة auth.loggedIn من true . سيعيد توجيههم إلى صفحة تسجيل الدخول باستخدام خيار إعادة التوجيه الخاص بنا في ملف تكوين المصادقة - إذا لم تقم بتسجيل الدخول وحاولت زيارة /my-report أو report-incident ، فسيتم إعادة توجيهك إلى /login .

إذا ذهبت إلى /report-incidents ، فهذا ما يجب أن تراه.

استمارة التبليغ عن الحوادث
صفحة الإبلاغ عن الحادث. (معاينة كبيرة)

هذه الصفحة مخصصة لإضافة الحوادث ولكن في الوقت الحالي لا يرسل النموذج حادثًا إلى خادمنا لأننا لا نقوم بالاتصال بالخادم عندما يحاول المستخدم إرسال النموذج. لحل هذه المشكلة ، سنضيف طريقة reportIncident والتي سيتم استدعاؤها عندما ينقر المستخدم على Report . سيكون لدينا هذا في قسم البرنامج النصي للمكون. سترسل هذه الطريقة بيانات النموذج إلى الخادم. قم بتحديث ملف report-incident.vue الخاص بك بما يلي:

 <template> <section class="report"> <h1 class="report__heading">Report an Incident</h1> <form class="report__form"> <div class="input__container"> <label for="title" class="input__label">Title</label> <input type="text" name="title" v-model="incident.title" class="input__field" required /> </div> <div class="input__container"> <label for="location" class="input__label">Location</label> <input type="text" name="location" v-model="incident.location" required class="input__field" /> </div> <div class="input__container"> <label for="comment" class="input__label">Comment</label> <textarea name="comment" v-model="incident.comment" class="input__area" cols="30" rows="10" required ></textarea> </div> <input type="submit" value="Report" class="input__button" @click.prevent="reportIncident" /> <p class="loading__indicator" v-if="loading">Please wait....</p> </form> </section> </template> <script> export default { name: "report-incident", middleware: "auth", data() { return { loading: false, incident: { type: "red-flag", title: "", location: "", comment: "" } }; }, methods: { async reportIncident() { let data = this.incident; let formData = new FormData(); formData.append("title", data.title); formData.append("type", data.type); formData.append("location", data.location); formData.append("comment", data.comment); this.loading = true; try { let res = await this.$store.dispatch("reportIncident", formData); this.$notify({ group: "success", title: "Success", text: "Incident reported successfully!" }); this.loading = false; this.$router.push("/my-reports"); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } } }; </script> <style> </style>

هنا ، لدينا نموذج يحتوي على حقول إدخال للعنوان والموقع والتعليق بربط بيانات ثنائي الاتجاه باستخدام v-model . لدينا أيضًا زر submit بحدث نقرة. في قسم البرنامج النصي ، لدينا طريقة reportIncident تجمع جميع المعلومات المقدمة في النموذج ويتم إرسالها إلى خادمنا باستخدام FormData لأن واجهة برمجة التطبيقات مصممة لقبول أيضًا الصور ومقاطع الفيديو.

يتم إرفاق بيانات النموذج هذا formData باستخدام طريقة الإرسال ، إذا كان الطلب ناجحًا ، فسيتم إعادة توجيهك إلى /my-reports مع إشعار يخبرك بأن هذا الطلب كان ناجحًا وإلا فسيتم إخطارك بخطأ في رسالة الخطأ .

في هذه المرحلة ، ليس لدينا إجراء reportIncident في متجرنا حتى الآن ، لذا في وحدة تحكم المتصفح لديك ، سترى خطأ إذا حاولت النقر فوق إرسال في هذه الصفحة.

رسالة الخطأ "[Vuex] نوع إجراء غير معروف: reportIncident"
رسالة خطأ Vuex. (معاينة كبيرة)

لإصلاح ذلك ، أضف الإجراء reportIncident الخاص بك في ملف index.js .

 export const actions = { // ... async reportIncident({}, data) { let res = await this.$axios.post('/incident/create', data) return res; } }

هنا ، لدينا وظيفة reportIncident تأخذ كائن سياق فارغ والبيانات التي نرسلها من النموذج الخاص بنا. يتم إرفاق هذه البيانات بعد ذلك بطلب post يؤدي إلى وقوع حادث ويعود مرة أخرى إلى ملف report-incident.vue بنا.

في هذه المرحلة ، يجب أن تكون قادرًا على إضافة تقرير باستخدام النموذج وبعد ذلك سيتم إعادة توجيهك إلى /my-reports .

صفحة تقاريري فارغة
صفحة تقاريري فارغة. (معاينة كبيرة)

يجب أن تعرض هذه الصفحة قائمة بالأحداث التي أنشأها المستخدم ولكنها الآن تعرض فقط ما نراه أعلاه ، دعنا نمضي قدمًا لإصلاح ذلك.

سنستخدم طريقة fetch التي تعلمناها للحصول على هذه القائمة. قم بتحديث ملف my-reports.vue بما يلي:

 <script> import incidentCard from "@/components/incidentCard.vue"; export default { middleware: "auth", name: "my-reports", data() { return { incidents: [] }; }, components: { incidentCard }, async fetch() { let { data } = await this.$axios.get("/user/incidents"); this.incidents = data.data; } }; </script>

هنا ، نستخدم طريقة fetch للحصول على الحوادث الخاصة بالمستخدم وتعيين الاستجابة لمجموعة الحوادث الخاصة بنا.

إذا قمت بتحديث صفحتك بعد إضافة حادثة ، فمن المفترض أن ترى شيئًا كهذا.

صفحة تقاريري مع تقرير واحد
صفحة تقاريري مع تقرير. (معاينة كبيرة)

في هذه المرحلة ، نلاحظ اختلافًا في كيفية تحميل طريقة fetch والبيانات asyncData .

خاتمة

حتى الآن ، تعرفنا على وحدة Axios وجميع ميزاتها. لقد تعلمنا أيضًا المزيد حول البيانات غير المتزامنة ، وكيف يمكننا إحضارهما معًا على الرغم من الاختلافات بينهما. لقد تعلمنا أيضًا كيفية إجراء المصادقة في تطبيقنا باستخدام وحدة المصادقة وكيفية استخدام البرمجيات الوسيطة auth لحماية مساراتنا. فيما يلي بعض الموارد المفيدة التي تتحدث أكثر عن كل ما قمنا بتغطيته.

  • الشروع في استخدام العلامات الوصفية في Nuxjs.
  • استخدام وحدة dotenv في Nuxt.
  • استخدام الجلب في تطبيق Nuxt الخاص بك.
  • الشروع في العمل مع AsyncData.

موارد

  1. "وحدة المصادقة ،" NuxtJS.org
  2. "وحدة Axios: مقدمة" ، NuxtJS.org
  3. FormData ، مستندات الويب MDN
  4. "API: طريقة البيانات غير المتزامنة ،" asyncData
  5. "The Vue Instance: Lifecycle Diagram ،" VueJS.org
  6. "فهم كيفية عمل fetch في Nuxt 2.12 ،" NuxtJS.org