كيفية إنشاء مدير موسيقى باستخدام Nuxt.js و Express.js
نشرت: 2022-03-10قد يكون التعامل مع أصول الوسائط الرقمية مثل الصوت والفيديو في تطبيقك أمرًا صعبًا بسبب الاعتبارات التي يجب إجراؤها من جانب الخادم (مثل الشبكات والتخزين والطبيعة غير المتزامنة للتعامل مع تحميلات الملفات). ومع ذلك ، يمكننا استخدام مكتبات مثل Multer و Express.js لتبسيط سير العمل على الواجهة الخلفية أثناء استخدام Nuxt.js (إطار عمل Vue) لبناء تفاعلات الواجهة الأمامية.
عندما يقوم عميل الويب بتحميل ملف إلى خادم ، يتم إرساله بشكل عام من خلال نموذج ويتم ترميزه على أنه multipart/form-data
. Multer
هو برنامج وسيط لـ Express.js و Node.js يجعل من السهل التعامل مع ما يسمى multipart/form-data
كلما قام المستخدمون بتحميل الملفات. في هذا البرنامج التعليمي ، سأشرح كيف يمكنك إنشاء تطبيق مدير الموسيقى باستخدام Express.js مع Multer لتحميل الموسيقى و Nuxt.js (إطار عمل Vue) للواجهة الأمامية الخاصة بنا.
المتطلبات الأساسية
- الإلمام بـ HTML و CSS و JavaScript (ES6 +) ؛
- تثبيت Node.js و npm و MongoDB على جهاز التطوير الخاص بك ؛
- كود VS أو أي محرر كود من اختيارك ؛
- المعرفة الأساسية لـ Express.js.
بناء الخدمة الخلفية
لنبدأ بإنشاء دليل لمشروعنا بالانتقال إلى الدليل ، وإصدار npm init -y
على جهازك لإنشاء ملف package.json يدير جميع التبعيات لتطبيقنا.
mkdir serverside && cd serverside npm init -y
بعد ذلك ، قم بتثبيت multer
، و express
، والاعتمادات الأخرى اللازمة لـ Bootstrap تطبيق Express.js.
npm install express multer nodemon mongoose cors morgan body-parser --save
بعد ذلك ، أنشئ ملف index.js :
touch index.js
بعد ذلك ، في ملف index.js ، سنهيئ جميع الوحدات ، وننشئ تطبيق Express.js ، وننشئ خادمًا للاتصال بالمتصفحات:
const express = require("express"); const PORT = process.env.PORT || 4000; const morgan = require("morgan"); const cors = require("cors"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); const config = require("./config/db"); const app = express(); //configure database and mongoose mongoose.set("useCreateIndex", true); mongoose .connect(config.database, { useNewUrlParser: true }) .then(() => { console.log("Database is connected"); }) .catch(err => { console.log({ database_error: err }); }); // db configuaration ends here //registering cors app.use(cors()); //configure body parser app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); //configure body-parser ends here app.use(morgan("dev")); // configire morgan // define first route app.get("/", (req, res) => { res.json("Hola MEVN devs...Assemble"); }); app.listen(PORT, () => { console.log(`App is running on ${PORT}`); });
أولاً وقبل كل شيء ، نجلب Express.js إلى المشروع ثم نحدد المنفذ الذي سيعمل عليه تطبيقنا. بعد ذلك ، نحضر تبعيات body-parser
، morgan
، mongoose
cors
.
ثم نحفظ المثيل السريع في متغير يسمى app
. يمكننا استخدام نسخة app
لتكوين البرامج الوسيطة في تطبيقنا تمامًا كما قمنا بتكوين البرامج الوسيطة cors
. نستخدم أيضًا مثيل app
لإعداد مسار الجذر الذي سيتم تشغيله في المنفذ الذي حددناه.
لنقم الآن بإنشاء مجلد /config
config
قاعدة البيانات الخاصة بنا وتكوين multer
:
mkdir config and cd config touch multer.js && touch db.js
ثم افتح config / db.js وأضف الكود التالي لتكوين قاعدة البيانات الخاصة بنا:
module.exports = { database: "mongodb://localhost:27017/", secret: "password" };
(هذا في الواقع كائن يحمل عنوان URL لقاعدة البيانات وسر قاعدة البيانات.)
تشغيل nodemon
والانتقال إلى localhost:4000
على متصفحك هذه الرسالة:
"Hola MEVN devs...Assemble"
أيضًا ، هذا هو الشكل الذي يجب أن يبدو عليه جهازك الطرفي الآن:

إعداد النموذج والطرق وأجهزة التحكم
لنقم بإعداد بنية ملف عن طريق كتابة ما يلي:
mkdir api && cd api mkdir model && cd model && touch Music.js cd .. mkdir controller && cd controller && touch musicController.js cd .. mkdir routes && cd routes && touch music.js
في طرفنا ، نستخدم mkdir
لإنشاء دليل جديد ، ثم cd
للانتقال إلى دليل. لذلك نبدأ بإنشاء دليل يسمى api
ثم ننتقل إلى دليل api
.
يتم استخدام الأمر touch
لإنشاء ملف جديد داخل دليل باستخدام المحطة الطرفية ، بينما يتم استخدام الأمر cd
للانتقال من دليل.
الآن دعنا ننتقل إلى ملف api / model / Music.js الخاص بنا لإنشاء مخطط موسيقى. النموذج هو فئة نبني بها المستندات. في هذه الحالة ، سيكون كل مستند مقطوعة موسيقية بخصائص وسلوكيات كما هو معلن في مخططنا:
let mongoose = require("mongoose"); let musicSchema = mongoose.Schema({ title: { type: String, required: true }, music: { type: Object, required: true }, artist: { type: String, required: true }, created: { type: Date, default: Date.now() } }); let Music = mongoose.model("Music", musicSchema); module.exports = Music;
دعنا ننتقل إلى config/multer
لتكوين Multer:
let multer = require("multer"); const path = require("path"); const storage = multer.diskStorage({ destination: (req, res, cb) => { cb(null, "./uploads"); }, filename: (req, file, cb) => { cb(null, new Date().toISOString() + file.originalname); } }); const fileFilter = (req, file, cb) => { if ( file.mimetype === "audio/mpeg" || file.mimetype === "audio/wave" || file.mimetype === "audio/wav" || file.mimetype === "audio/mp3" ) { cb(null, true); } else { cb(null, false); } }; exports.upload = multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 5 }, fileFilter: fileFilter });
في ملف multer.js ، نبدأ بإعداد مجلد يتم فيه تحميل جميع ملفات الموسيقى التي تم تحميلها. نحتاج إلى جعل هذا الملف ثابتًا من خلال تحديد ذلك في ملف index.js :
app.use('/uploads', express.static('uploads'));
بعد ذلك ، نكتب مدققًا بسيطًا يتحقق من نوع الملف قبل التحميل . ثم نقوم بتعريف مثيل multer
عن طريق إضافة موقع التخزين ، وحدود كل ملف ، والمدقق الذي أنشأناه.
قم بإنشاء الطرق الضرورية
لنقم الآن بإنشاء طرقنا. فيما يلي قائمة بالنقاط النهائية التي سننشئها.
HTTP POST /music | أضف موسيقى جديدة |
HTTP GET /music | احصل على كل الموسيقى |
HTTP DELETE /music/:blogId | احذف الموسيقى |
لنبدأ بإنشاء مسار المدونة. توجه إلى api /ways / music.js واكتب الكود التالي:
const express = require("express"); const router = express.Router(); const musicController = require("../controller/musicController"); const upload = require("../../config/multer"); router.get("/", musicController.getAllMusics); router.post("/", upload.upload.single("music"), musicController.addNewMusic); router.delete("/:musicId", musicController.deleteMusic); module.exports = router;
ملاحظة : الآن كلما قدمنا طلب get
على /music
. يستدعي المسار وظيفة getAllMusic
الموجودة في ملف "وحدات التحكم".
دعنا ننتقل إلى api/controllers/musicController
لتحديد وحدات التحكم. نبدأ بكتابة دالة للحصول على كل الموسيقى في قاعدة البيانات الخاصة بنا باستخدام طريقة mongoose db.collection.find
التي ستعيد جميع العناصر الموجودة في تلك المجموعة.
بعد القيام بذلك ، نكتب وظيفة أخرى من شأنها إنشاء مقطوعة موسيقية جديدة في قاعدة البيانات. نحتاج إلى إنشاء مثيل موسيقى جديد باستخدام الكلمة الأساسية new
ثم تحديد كائن الموسيقى. بعد القيام بذلك ، سنستخدم طريقة save
النمس لإضافة موسيقى جديدة إلى قاعدة البيانات.
لحذف قطعة موسيقية ، نحتاج إلى استخدام طريقة remove
النمس عن طريق تمرير معرف الموسيقى كمعامل في مثيل remove
. ينتج عن هذا النمس البحث في مجموعة الموسيقى التي تحتوي على هذا المعرف المعين ثم إزالتها من تلك المجموعة.
let mongoose = require("mongoose"); const Music = require("../model/Music"); exports.getAllMusics = async (req, res) => { try { let music = await Music.find(); res.status(200).json(music); } catch (err) { res.status(500).json(err); } }; exports.addNewMusic = async (req, res) => { try { const music = new Music({ title:req.body.title, artist:req.body.artist, music:req.file }); let newMusic = await music.save(); res.status(200).json({ data: newMusic }); } catch (err) { res.status(500).json({ error: err }); } }; exports.deleteMusic = async (req, res) => { try { const id = req.params.musicId; let result = await Music.remove({ _id: id }); res.status(200).json(result); } catch (err) { res.status(500).json(err); } };
أخيرًا وليس آخرًا ، لاختبار المسارات ، نحتاج إلى تسجيل مسارات الموسيقى في ملف index.js الخاص بنا:
const userRoutes = require("./api/user/route/user"); //bring in our user routes app.use("/user", userRoutes);
اختبار نقاط النهاية
لاختبار نقاط النهاية لدينا ، سنستخدم POSTMAN.
مضيفا موسيقى جديدة
لاختبار وظيفة Add Music
، اضبط طريقة الطلب بالنقر فوق القائمة المنسدلة للطرق. بعد القيام بذلك ، اكتب عنوان URL لنقطة النهاية ، ثم انقر فوق علامة تبويب النص الأساسي لتحديد الطريقة التي تريد بها إرسال بياناتك. (في حالتنا ، سنستخدم طريقة بيانات النموذج.)
لذا انقر فوق بيانات النموذج وقم بإعداد مفتاح النموذج الخاص بك. أثناء إعداده ، امنح المفاتيح بعض القيمة كما هو موضح في الصورة أدناه:

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

حذف الموسيقى
لحذف قطعة موسيقية ، نحتاج إلى تمرير music id
.

هذا هو!
بناء الواجهة
بالنسبة إلى الواجهة الأمامية ، سنستخدم إطار عمل Vue: Nuxt.js.
"Nuxt هو إطار عمل تقدمي يعتمد على Vue.js لإنشاء تطبيقات ويب حديثة. ويستند إلى مكتبات Vue.js الرسمية (vue و vue-router و vuex) وأدوات التطوير القوية (webpack و Babel و PostCSS). "
- دليل NuxtJS
لإنشاء تطبيق Nuxt.js جديد ، افتح جهازك واكتب ما يلي (باستخدام musicapp
كاسم التطبيق الذي سنبنيه):
$ npx create-nuxt-app musicapp
أثناء عملية التثبيت ، سيتم طرح بعض الأسئلة علينا بخصوص إعداد المشروع:
Project name | musicapp |
project description | تطبيق مدير موسيقى بسيط |
Author name | <اسمك> |
Package manager | npm |
UI framework | Bootstrap vue |
custom ui framework | لا أحد |
Nuxt modules | Axios ، pwa (استخدم مفتاح المسافة على لوحة المفاتيح لتحديد العناصر) |
Linting tool | أجمل |
test framework | لا أحد |
Rendering Mode | عالمي (SSR) |
development tool | Jsonconfig.json |
بعد تحديد كل هذا ، يتعين علينا الانتظار قليلاً حتى يتم إعداد المشروع. بمجرد أن يصبح جاهزًا ، انتقل إلى مجلد /project
وقم بخدمة المشروع على النحو التالي:
cd musicapp && npm run dev
افتح المشروع في أي محرر كود من اختيارك ، ثم افتح المشروع في المتصفح عن طريق الوصول إلى localhost:3000
.

تكوين Axios
سنستخدم المحاور لتقديم طلب HTTP axios
الخلفي. تم تثبيت Axios بالفعل في مشروعنا ، لذلك علينا فقط تكوين عنوان URL الأساسي - baseURL
الخلفي.
للقيام بذلك ، افتح ملف nuxt.config.js في الدليل root
وأضف baseURL
في كائن axios
.
axios: { baseURL:'https://localhost:4000' },
بناء مدير الموسيقى
إعداد واجهة المستخدم
لنبدأ بتنظيف واجهة المستخدم. افتح ملف pages / index.vue وقم بإزالة جميع التعليمات البرمجية الموجودة هناك بما يلي:
<template> <div>Hello</div> </template>
بعد القيام بذلك ، يجب أن تكون قادرًا فقط على رؤية كلمة "مرحبًا" في المتصفح.
في الدليل root
، قم بإنشاء مجلد /partials
. داخل مجلد /partials
parts ، أنشئ ملف navbar.vue وأضف الكود التالي:
<template> <header> <nav class="navbar navbar-expand-lg navbar-light bg-info"> <div class="container"> <a class="navbar-brand" href="#">Music App</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation" > <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse justify-content-end"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" href="#">Player</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Manager</a> </li> </ul> </div> </div> </nav> </header> </template> <style scoped> .nav-link, .navbar-brand { color: #ffff !important; } </style>
ملاحظة : سنستخدم المكون للتنقل عبر الصفحات في تطبيقنا. سيكون هذا مجرد مكون بسيط مكون من Bootstrap navbar
. تحقق من وثائق Bootstrap الرسمية لمزيد من المراجع.
بعد ذلك ، دعنا نحدد تخطيطًا مخصصًا للتطبيق. افتح المجلد /layouts
، واستبدل الكود الموجود في ملف default.vue بالرمز أدناه.
<template> <div> <navbar /> <nuxt /> </div> </template> <script> import navbar from '@/partial/navbar' export default { components: { navbar } } </script>
نقوم باستيراد navbar
في هذا التخطيط ، مما يعني أن جميع الصفحات في تطبيقنا ستحتوي على مكون navbar
هذا. (سيكون هذا هو المكون الذي سيتم تثبيت جميع المكونات الأخرى في تطبيقنا.)
بعد ذلك ، يجب أن تكون قادرًا على رؤية هذا في متصفحك:

لنقم الآن بإعداد واجهة المستخدم لمديرنا. للقيام بذلك ، نحتاج إلى إنشاء مجلد /manager
داخل مجلد المكونات ثم إضافة ملف إلى المجلد باسم manager.vue .
أضف الكود التالي في هذا الملف:
<template> <section class="mt-5"> <div class="container mb-4"> <div class="row"> <div class="col-md-12"> <div class="card"> <div class="card-body"> <div class="card-title mb-4"> <h4>Add Music</h4> </div> <form> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="artist">Artist</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="artist">Music</label> <div class="custom-file"> <input type="file" class="custom-file-input" /> <label class="custom-file-label" for="customFile">Choose file</label> </div> </div> <div class="form-group"> <button class="btn btn-primary">Submit</button> </div> </form> </div> </div> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="card bg-light p-1 showdow-sm"> <div class="card-title"> <button class="btn btn-info m-3">Add Music</button> </div> <div class="card-body"> <table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">Title</th> <th scope="col">Artist</th> <th scope="col">Date created</th> <th scope="col">Action</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>Demo Title</td> <td>Wisdom.vue</td> <td>12/23/13</td> <td> <button class="btn btn-info">Delete</button> </td> </tr> </tbody> </table> </div> </div> </div> </div> </div> </section> </template>
ملاحظة : هذا مجرد قالب Bootstrap بسيط لإضافة الموسيقى إلى تطبيقنا. سيحدد النموذج قالب جدول يسرد جميع ملفات الموسيقى التي يمكن العثور عليها في قاعدة البيانات الخاصة بنا.
بعد تحديد هذا المكون ، نحتاج إلى تسجيله في مجلد /pages
لبدء التوجيه.
لا يحتوي Nuxt.js على ملف "router.js" مثل Vue.js. يستخدم مجلد الصفحات للتوجيه. لمزيد من التفاصيل ، قم بزيارة موقع Nuxt.js.
لتسجيل المكون ، أنشئ مجلد /manager
داخل مجلد /pages
وأنشئ ملف index.vue . ثم ضع الكود التالي داخل الملف:
<template> <div> <manager /> </div> </template> <script> import manager from '@/components/manager/manager' export default { components: { manager } } </script>
هذا هو المكون الذي سيتم عرضه في مسار pages
.
بعد القيام بذلك ، توجه إلى متصفحك وانتقل إلى /manager
- يجب أن ترى هذا:


سرد جميع الموسيقى
دعنا نواصل من خلال إنشاء وظيفة تجلب كل الموسيقى. سيتم تسجيل هذه الوظيفة في خطاف دورة الحياة الذي تم إنشاؤه ، بحيث يتم استدعاء الوظيفة كلما تم إنشاء المكون.
لنبدأ بإنشاء متغير في مثيل vue
سيحمل كل الموسيقى:
allmusic = []; musicLoading: false,
بعد ذلك ، حدد دالة getAllMusics
وأضف الكود التالي:
async getAllMusics() { this.musicLoading = true try { let data = await this.$axios.$get('/music') this.allmusic = data this.musicLoading = false } catch (err) { this.musicLoading = false swal('Error', 'Error Fetting Musics', 'error') } }
بعد ذلك ، قم بالتسجيل في خطاف دورة الحياة الذي تم إنشاؤه:
created() { this.getAllMusics() }
إخراج البيانات
حان الوقت الآن لإخراج جميع الأغاني التي أنشأناها سابقًا على المنضدة:
<table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">Title</th> <th scope="col">Artist</th> <th scope="col">Date created</th> <th scope="col">Action</th> </tr> </thead> <div v-if="musicLoading" class="spinner-border" role="status" > <span class="sr-only">Loading...</span> </div> <tbody v-else> <tr v-for="(music, index) in allmusic" :key="index"> <td>{{ index + 1 }}</td> <td>{{ music.title }}</td> <td>{{ music.artist }}</td> <td>{{ music.created }}</td> <td> <button class="btn btn-info" @click="deleteMusic(music._id)">Delete</button> </td> </tr> </tbody> </table>
تذكر هذا الجدول الذي أنشأناه في وقت سابق؟ حسنًا ، سنحتاج إلى تكرار الاستجابة التي نحصل عليها من الواجهة الخلفية لدينا لإدراج جميع الموسيقى التي تم تلقيها من قاعدة البيانات.
مضيفا الموسيقى
لإضافة مقطوعة موسيقية جديدة ، نحتاج إلى تقديم طلب HTTP إلى خادم النهاية مع تفاصيل الموسيقى. للقيام بذلك ، لنبدأ بتعديل النموذج والتعامل مع تحميلات الملف.
في النموذج ، نحتاج إلى إضافة مستمع event
الذي سيستمع إلى النموذج عند تقديمه. في حقل input
، نضيف نموذج v-
لربط القيمة بحقل الإدخال.
<form @submit.prevent="addNewMusic"> <div class="form-group"> <label for="title">Title</label> <input type="text" v-model="musicDetails.title" class="form-control" /> </div> <div class="form-group"> <label for="artist">Artist</label> <input type="text" v-model="musicDetails.artist" class="form-control" /> </div> <div class="form-group"> <label for="artist">Music</label> <div class="custom-file"> <input type="file" ref="file" v-on:change="handleFileUpload()" class="custom-file-input" /> <label class="custom-file-label" for="customFile">Choose file</label> </div> </div> <div class="form-group"> <button class="btn btn-primary" :disabled="isDisabled"> <span class="spinner-border spinner-border-sm" v-if="addLoading" role="status" aria-hidden="true" ></span>Submit </button> </div> </form>
ويجب أن يبدو قسم البرنامج النصي كما يلي:
<script> export default { data() { return { musicDetails: { title: '', artist: '', music: '' }, allmusic = [], musicLoading: false, isValid: false; addLoading: false, } }, computed: { isDisabled: function() { if ( this.musicDetails.title === '' || this.musicDetails.artist === '' || this.musicDetails.music === '' ) { return !this.isValid } } }, methods: { handleFileUpload() { this.musicDetails.music = this.$refs.file.files[0] console.log(this.musicDetails.music.type) }, addNewMusic() { let types = /(\.|\/)(mp3|mp4)$/i if ( types.test(this.musicDetails.music.type) || types.test(this.musicDetails.music.name) ) { console.log('erjkb') } else { alert('Invalid file type') return !this.isValid } } } } </script>
سنحدد الوظيفة التي سترسل طلبًا إلى خدمتنا الخلفية لإنشاء أي موسيقى جديدة تمت إضافتها إلى القائمة. أيضا. نحتاج إلى كتابة دالة تحقق بسيطة تتحقق من نوع الملف بحيث يمكن للمستخدمين فقط تحميل الملفات ذات الامتداد .mp3 و. mp4 .
من المهم تحديد خاصية محسوبة للتأكد من أن حقل الإدخال ليس فارغًا. نحتاج أيضًا إلى إضافة مدقق بسيط للتأكد من أن الملف الذي نحاول تحميله هو في الواقع ملف موسيقى.
دعنا نواصل تحرير وظيفة addMusic
لتقديم طلب إلى الخدمة الخلفية لدينا. ولكن قبل القيام بذلك ، دعنا أولاً sweetalert
الذي سيوفر لنا نافذة مشروطة لطيفة. للقيام بذلك ، افتح الجهاز واكتب ما يلي:
npm i sweetalert
بعد تثبيت الحزمة ، قم بإنشاء ملف sweetalert.js في مجلد /plugins
وأضف هذا:
import Vue from 'vue'; import swal from 'sweetalert'; Vue.prototype.$swal = swal;
بعد ذلك ، قم بتسجيل المكون الإضافي في ملف nuxt.config.js داخل المكون الإضافي instace مثل هذا:
plugins: [ { src: '~/plugins/sweetalert' } ],
لقد قمنا الآن بتكوين sweetalert
بنجاح في تطبيقنا ، حتى نتمكن من المضي قدمًا وتحرير وظيفة addmusic
إلى هذا:
addNewMusic() { let types = /(\.|\/)(mp3|mp4)$/i if ( types.test(this.musicDetails.music.type) || types.test(this.musicDetails.music.name) ) { let formData = new FormData() formData.append('title', this.musicDetails.title) formData.append('artist', this.musicDetails.artist) formData.append('music', this.musicDetails.music) this.addLoading = true this.$axios .$post('/music', formData) .then(response => { console.log(response) this.addLoading = false this.musicDetails = {} this.getAllMusics() // we will create this function later swal('Success', 'New Music Added', 'success') }) .catch(err => { this.addLoading = false swal('Error', 'Something Went wrong', 'error') console.log(err) }) } else { swal('Error', 'Invalid file type', 'error') return !this.isValid } },
دعنا نكتب نصًا بسيطًا من شأنه تبديل النموذج ، أي يجب أن يتم عرضه فقط عندما نريد إضافة موسيقى جديدة.
يمكننا القيام بذلك عن طريق تحرير زر "إضافة موسيقى" في الجدول الذي يعرض كل الموسيقى التي يمكن العثور عليها:
<button class="btn btn-info m-3" @click="initForm"> {{addState?"Cancel":"Add New Music"}} </button>
بعد ذلك ، أضف حالة ستحتفظ بحالة النموذج في خاصية data
:
addState: false
بعد القيام بذلك ، دعنا نحدد وظيفة initForm
:
initForm() { this.addState = !this.addState },
ثم أضف v-if="addState"
إلى div
الذي يحتوي على النموذج:
<div class="card" v-if="addState">
حذف الموسيقى
لحذف الموسيقى ، نحتاج إلى استدعاء نقطة نهاية delete
وتمرير music id
كمعلمة. دعنا نضيف حدث click
إلى الزر "حذف" والذي سيشغل الوظيفة لحذف وظيفة:
<button class="btn btn-info" @click="deleteMusic(music._id)">Delete</button>
ستعمل وظيفة delete
على تقديم طلب HTTP إلى خدمتنا الخلفية. بعد الحصول على معرف الموسيقى من معلمة وظيفة deleteMusic
، سنضيف المعرف في عنوان URL الذي نستخدمه لإرسال الطلب. يحدد هذا بالضبط قطعة الموسيقى التي يجب إزالتها من قاعدة البيانات.
deleteMusic(id) { swal({ title: 'Are you sure?', text: 'Once deleted, you will not be able to recover this Music!', icon: 'warning', buttons: true, dangerMode: true }).then(willDelete => { if (willDelete) { this.$axios .$delete('/music/' + id) .then(response => { this.getAllMusics() swal('Poof! Your Music file has been deleted!', { icon: 'success' }) }) .catch(err => { swal('Error', 'Somethimg went wrong', 'error') }) } else { swal('Your Music file is safe!') } }) }
مع كل هذا ، قمنا للتو ببناء مدير الموسيقى الخاص بنا. حان الوقت الآن لبناء مشغل الموسيقى.
لنبدأ بإنشاء مجلد جديد في مجلد المكونات المسمى /player
. ثم قم بإنشاء ملف player.vue داخل هذا المجلد وأضف هذا:
<template> <section> <div class="container"> <div class="row"> <div class="col-md-12"> <h3 class="text-center">Player</h3> </div> </div> </div> </section> </template> <script> export default { data() { return {} } } </script> <style scoped> </style>
بعد ذلك ، دعنا نستورد هذا المكون إلى ملف index.vue في مجلد /pages
. استبدل الكود الموجود في ملف index.vue بهذا:
<template> <div> <player /> </div> </template> <script> import player from '@/components/player/player' export default { components: { player } } </script>
لنقم بتهيئة التوجيه في مكون navbar
الخاص بنا لتمكين التوجيه بين صفحاتنا.
للتوجيه في تطبيق Nuxt.js ، يتم استخدام nuxt-link
وبعد ذلك حددت الصفحة لهذا المسار إلى مثيل معين. لذلك دعونا نعدل الكود في مكون الأجزاء partials/navbar
إلى هذا:
<template> <header> <nav class="navbar navbar-expand-lg navbar-light bg-info"> <div class="container"> <nuxt-link to="/" class="navbar-brand">Music App</nuxt-link> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation" > <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse justify-content-end"> <ul class="navbar-nav"> <li class="nav-item active"> <nuxt-link to="/" class="nav-link">Player</nuxt-link> </li> <li class="nav-item"> <nuxt-link to="/manager" class="nav-link">Manager</nuxt-link> </li> </ul> </div> </div> </nav> </header> </template> <style scoped> .nav-link, .navbar-brand { color: #ffff !important; } </style>
باستخدام هذا ، يمكننا التنقل عبر صفحاتنا باستخدام شريط التنقل.
بناء اللاعب
قبل أن نبدأ ، نحتاج إلى توسيع Webpack لتحميل الملفات الصوتية. يجب معالجة الملفات الصوتية بواسطة أداة file-loader
. تم تضمين أداة التحميل هذه بالفعل في تكوين Webpack الافتراضي ، ولكن لم يتم إعدادها للتعامل مع الملفات الصوتية.
للقيام بذلك ، انتقل إلى ملف nuxt.config.js وقم بتعديل كائن build
إلى هذا:
build: { extend(config, ctx) { config.module.rules.push({ test: /\.(ogg|mp3|mp4|wav|mpe?g)$/i, loader: 'file-loader', options: { name: '\[path\][name].[ext]' } }) } }
بعد ذلك ، دعنا نكتب وظيفة ستحصل على جميع الأغاني ثم نستخدم مُنشئ Audio
لتشغيل الأغنية الأولى في مصفوفة allMusic
.
بالنسبة للمبتدئين ، دعنا نعدل ملف player.vue الخاص بنا إلى هذا:
<template> <section v-if="allMusic"> <div class="container"> <div class="row"> <div class="col-md-12"> <h3 class="text-center">Player</h3> </div> </div> <div class="row"> <div class="col-md-6"> <span>{{this.current.title}} - {{this.current.artist}}</span> </div> </div> </div> </section> </template> <script> export default { data() { return { current: { title: '', artist: '' }, song: true, isplaying: false, allMusic: null, index: 0, player: '' } }, methods: { async initPlayer() { if (this.allMusic !== []) { this.current = await this.allMusic[this.index] this.player.src = `https://localhost:4000/${this.current.music.path}` } else { this.song = true } }, async getAllSongs() { try { let response = await this.$axios.$get('/music') console.log(response) if (response === []) { this.song = true this.current = null } else { this.song = false this.allMusic = response } await this.initPlayer() } catch (err) { this.current = null console.log(err) } } }, created() { if (process.client) { this.player = new Audio() } this.getAllSongs() } } </script> <style scoped> </style>
بمجرد تقديم الملف ، سيتم تشغيل الموسيقى في الخلفية وبعد ذلك يجب أن تكون قادرًا على رؤية ذلك في متصفحك:

لإيقاف الموسيقى ، كل ما عليك فعله هو التعليق على await player.play()
في وظيفة initPlayer
.
إنشاء واجهة مستخدم المشغل
دعنا الآن نحدد واجهة مستخدم مشغل الموسيقى الخاصة بنا عن طريق استبدال القالب الموجود في ملف player.vue بما يلي:
<template> <section v-if="allMusic"> <div class="container"> <div class="row mb-5"> <div class="col-md-12"> <h3 class="text-center">Player</h3> </div> </div> <div class="row mt-5"> <div class="col-md-6"> <img src="https://images.pexels.com/photos/3624281/pexels-photo-3624281.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" class="image" /> <div class="card player_card"> <div class="card-body"> <h6 class="card-title"> <b>{{this.current.title}} - {{this.current.artist}}</b> </h6> <div> <i class="fas fa-backward control mr-4"></i> <i class="fas fa-play play"></i> <i class="fas fa-pause play"></i> <i class="fas fa-forward control ml-4"></i> </div> </div> </div> </div> <div class="col-md-6"> <div class="card shadow"> <table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">Title</th> <th scope="col">Artist</th> <th scope="col">Action</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>Mark</td> <td>Otto</td> <td> <button class="btn btn-primary">Play</button> </td> </tr> </tbody> </table> </div> </div> </div> </div> </section> </template>
ثم أضف النمط التالي إلى قسم style
:
<style scoped> .image { border-radius: 5px !important; position: relative; height: 300px; width: 100%; } .player_card { text-align: center; bottom: 20px; margin: 0px 40px; } .text-muted { font-size: 15px; } .play { font-size: 40px; } .control { font-size: 25px; } </style>
بعد تعديل هذا ، يجب أن يبدو اللاعب كما يلي:

مضيفا وظيفة اللعب
سنستمر في عرض وصف الموسيقى على الطاولة. للقيام بذلك ، استبدل الجدول بالرمز أدناه:
<table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">Title</th> <th scope="col">Artist</th> <th scope="col">Action</th> </tr> </thead> <tbody> <tr v-for="(music,index) in allMusic" :key="index"> <th scope="row">{{index+1}}</th> <td>{{music.title}}</td> <td>{{music.artist}}</td> <td> <button class="btn btn-primary">Play</button> </td> </tr> </tbody> </table>
لا نريد عرض أيقونات "تشغيل" و "إيقاف مؤقت" في نفس الوقت. بدلاً من ذلك ، نريد موقفًا عندما يتم تشغيل الأغنية ، يتم عرض رمز "إيقاف مؤقت". أيضًا ، عند إيقاف الأغنية مؤقتًا ، يجب عرض رمز التشغيل.
لتحقيق ذلك ، نحتاج إلى تعيين حالة isPlaying
على مثيل false
ثم استخدام هذا المثال لتبديل الرموز. بعد ذلك ، سنضيف وظيفة إلى أيقونة "التشغيل" الخاصة بنا.
isplaying:false
بعد القيام بذلك ، قم بتعديل رمز "تشغيل" و "إيقاف مؤقت" إلى هذا:
<i class="fas fa-play play" v-if="!isplaying" @click="play"></i> <i class="fas fa-pause play" v-else></i>
مع كل هذا دعونا نحدد طريقة play
:
play(song) { console.log(song) if (song) { this.current = song this.player.src = `https://localhost:4000/${this.current.music.path}` } this.player.play() this.isplaying = true },
نحن ، أولاً وقبل كل شيء ، نحصل على الأغنية الحالية ونقوم بتمريرها إلى معلمة function
. ثم نحدد مثيل JavaScript Audio()
. بعد ذلك ، نتحقق مما إذا كانت الأغنية فارغة: إذا لم تكن كذلك ، فسنقوم بتعيين this.current
للأغنية التي مررناها في المعلمة ، ثم نسمي مثيل مشغل Audio
. (أيضًا ، لا تنس أنه يتعين علينا ضبط حالة isPlaying
على true
عند تشغيل الموسيقى.)
مضيفا وظيفة وقفة
لإيقاف أغنية مؤقتًا ، سنستخدم طريقة إيقاف Audio
. نحتاج إلى إضافة حدث click
إلى رمز الإيقاف المؤقت:
<i class="fas fa-pause play" @click="pause" v-else></i>
ثم حدد الوظيفة في methods
العمليات:
pause() { this.player.pause() this.isplaying = false },
تشغيل أغنية من قائمة الموسيقى
هذا سهل التنفيذ. كل ما يتعين علينا القيام به هو إضافة حدث click
سيغير معلمة song
في طريقة play
إلى الأغنية التي أنشأناها للتو.
ما عليك سوى تعديل زر play
على جدول قائمة الموسيقى إلى هذا:
<button class="btn btn-primary" @click="play(music)">Play</button>
وهناك لديك!
إضافة الوظيفة التالية
لإضافة الوظيفة التالية ، نحتاج إلى زيادة الفهرس بمقدار واحد. للقيام بذلك ، أضف حدث click
إلى الرمز التالي:
@click="next"
ثم حدد الوظيفة prev
في methods
العمليات:
next() { this.index++ if (this.index > this.allMusic.length - 1) { this.index = 0 } this.current = this.allMusic[this.index] this.play(this.current) },
هذا الشرط مسؤول عن إعادة تشغيل جميع الأغاني متى تم تشغيل آخر أغنية في القائمة.
إضافة الوظيفة previous
هذا في الواقع عكس الوظيفة التالية ، لذلك دعونا نضيف حدث click
إلى الوظيفة السابقة:
@click="prev"
بعد ذلك ، نحدد الوظيفة السابقة:
prev() { this.index-- if (this.index < 0) { this.index = this.allMusic.length - 1 } this.current = this.allMusic[this.index] this.play(this.current) },
تطبيق مشغل الموسيقى الخاص بنا اكتمل الآن!
خاتمة
في هذه المقالة ، نظرنا في كيفية إنشاء مدير موسيقى باستخدام Nuxt.js و Express.js. على طول الطريق ، رأينا كيف يبسط Multer عملية معالجة تحميلات الملفات وكيفية استخدام Mongoose للتفاعل بدون قاعدة بيانات. أخيرًا ، استخدمنا Nuxt.js لبناء تطبيق العميل الذي يمنحه إحساسًا سريعًا وسريعًا.
على عكس الأطر الأخرى ، فإن إنشاء تطبيق باستخدام Nuxt.js و Express.js سهل وسريع للغاية. الجزء الرائع في Nuxt.js هو الطريقة التي يدير بها مساراتك ويجعلك تقوم ببناء تطبيقاتك بشكل أفضل.
- يمكنك الوصول إلى مزيد من المعلومات حول Nuxt.js هنا.
- يمكنك الوصول إلى الكود المصدري على جيثب هنا