วิธีสร้างโปรแกรมจัดการเพลงด้วย Nuxt.js และ Express.js

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ บทความนี้จะแนะนำวิธีที่ Multer ปรับปรุงกระบวนการจัดการการอัปโหลดไฟล์ นอกจากนี้ยังแนะนำวิธีใช้ Mongoose เพื่อโต้ตอบกับฐานข้อมูลของเราโดยการสร้างแอปตัวจัดการเพลงโดยใช้ Express.js ควบคู่ไปกับ Multer สำหรับการอัปโหลดเพลงและ Nuxt.js (เฟรมเวิร์ก Vue) สำหรับส่วนหน้าของเรา

การจัดการทรัพย์สินสื่อดิจิทัล เช่น เสียงและวิดีโอในแอปพลิเคชันของคุณอาจเป็นเรื่องยุ่งยาก เนื่องจากข้อควรพิจารณาที่ต้องทำในฝั่งเซิร์ฟเวอร์ อย่างไรก็ตาม เราสามารถใช้ไลบรารีต่างๆ เช่น 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 dependencies

จากนั้นเราบันทึกอินสแตนซ์ด่วนในตัวแปรที่เรียกว่า app เราสามารถใช้อินสแตนซ์ของ app เพื่อกำหนดค่ามิดเดิลแวร์ในแอปพลิเคชันของเราได้เช่นเดียวกับที่เรากำหนดค่า cors ของคอร์ เรายังใช้อินสแตนซ์ของ app เพื่อตั้งค่าเส้นทางรูทที่จะทำงานในพอร์ตที่เรากำหนด

ตอนนี้มาสร้างโฟลเดอร์ /config สำหรับฐานข้อมูล config และ multer config:

 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"

นอกจากนี้ นี่คือสิ่งที่เทอร์มินัลของคุณควรมีลักษณะดังนี้:

เรียกใช้ Nodemon โดยใช้ Terminal
การแสดงตัวอย่างเทอร์มินัล (ตัวอย่างขนาดใหญ่)

การตั้งค่าโมเดล เส้นทาง และตัวควบคุม

มาตั้งค่าโครงสร้างไฟล์กันโดยพิมพ์ดังนี้

 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'));

หลังจากนั้น เราเขียนเครื่องมือตรวจสอบอย่างง่ายที่จะตรวจสอบประเภทไฟล์ mime ก่อนอัปโหลด จากนั้นเราจะกำหนดอินสแตนซ์ multer โดยเพิ่มตำแหน่งที่เก็บข้อมูล ขีดจำกัดของแต่ละไฟล์ และตัวตรวจสอบความถูกต้องที่เราสร้างขึ้น

สร้างเส้นทางที่จำเป็น

มาสร้างเส้นทางของเรากัน ด้านล่างนี้คือรายการปลายทางที่เราจะสร้าง

HTTP POST /music เพิ่มเพลงใหม่
HTTP GET /music รับทุกเพลง
HTTP DELETE /music/:blogId ลบเพลง

เริ่มต้นด้วยการสร้างเส้นทางบล็อก ตรงไปที่ api/routes/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 ที่อยู่ในไฟล์ 'controllers'

ไปที่ api/controllers/musicController เพื่อกำหนดคอนโทรลเลอร์ เราเริ่มต้นด้วยการเขียนฟังก์ชันเพื่อรับเพลงทั้งหมดในฐานข้อมูลของเราโดยใช้เมธอด mongoose db.collection.find ซึ่งจะส่งคืนรายการทั้งหมดในคอลเล็กชันนั้น

หลังจากทำอย่างนั้น เราเขียนฟังก์ชันอื่นที่จะสร้างเพลงใหม่ในฐานข้อมูล เราจำเป็นต้องสร้างอินสแตนซ์เพลงใหม่โดยใช้คำหลัก new แล้วกำหนดวัตถุเพลง หลังจากนี้เราจะใช้วิธี save พังพอนเพื่อเพิ่มเพลงใหม่ลงในฐานข้อมูล

ในการลบเพลง เราจำเป็นต้องใช้วิธีการ remove พังพอน โดยเพียงแค่ส่ง ID เพลงเป็นพารามิเตอร์ในอินสแตนซ์การ remove ส่งผลให้พังพอนมองเข้าไปในคอลเลคชันเพลงที่มี ID นั้น ๆ แล้วลบออกจากคอลเล็กชันนั้น

 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 ของปลายทาง จากนั้นคลิกที่แท็บเนื้อหาเพื่อเลือกวิธีที่คุณต้องการส่งข้อมูลของคุณ (ในกรณีของเรา เราจะใช้วิธี form-data)

ดังนั้นคลิกที่ form-data และตั้งค่ารหัสโมเดลของคุณ ในขณะที่คุณตั้งค่า ให้ตั้งค่าคีย์บางค่าตามที่แสดงในภาพด้านล่าง:

การทดสอบการเพิ่ม API เพลงใหม่โดยใช้ Postman
การทดสอบการเพิ่ม API เพลงใหม่ในแดชบอร์ดบุรุษไปรษณีย์ (ตัวอย่างขนาดใหญ่)

หลังจากทำเช่นนี้ ให้คลิกที่ 'ส่ง' เพื่อส่งคำขอ

รายชื่อเพลงทั้งหมด

ในการแสดงรายการเพลงทั้งหมดในฐานข้อมูลของเรา เราต้องพิมพ์ URL ปลายทางในส่วน URL ที่ให้ไว้ หลังจากทำเช่นนี้ ให้คลิกที่ปุ่ม 'ส่ง' เพื่อทำการร้องขอ

การทดสอบรายการ API โดยใช้บุรุษไปรษณีย์
การทดสอบรายการ API ในแดชบอร์ดบุรุษไปรษณีย์ (ตัวอย่างขนาดใหญ่)

การลบเพลง

ในการลบเพลง เราต้องส่ง music id เป็นพารามิเตอร์

การทดสอบลบ API โดยใช้ Postman
การทดสอบ Delete API Postman Dashboard (ตัวอย่างขนาดใหญ่)

แค่นั้นแหละ!

การสร้างส่วนหน้า

สำหรับส่วนหน้า เราจะใช้ Vue framework: 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 วิว
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

ดูตัวอย่างโครงการ Nuxt.js
ตัวอย่างโปรเจ็กต์ Nuxt.js (ตัวอย่างขนาดใหญ่)

การกำหนดค่า Axios

เราจะใช้ axios เพื่อส่งคำขอ HTTP ไปยังเซิร์ฟเวอร์ส่วนหลังของเรา Axios ได้รับการติดตั้งแล้วในโปรเจ็กต์ของเรา ดังนั้นเราแค่ต้องกำหนดค่า baseURL - ไปยังเซิร์ฟเวอร์แบ็กเอนด์ของเรา

ในการดำเนินการนี้ ให้เปิดไฟล์ nuxt.config.js ในไดเร็กทอรี root และเพิ่ม baseURL ในอ็อบเจ็กต์ axios

 axios: { baseURL:'https://localhost:4000' },

การสร้างผู้จัดการเพลง

การตั้งค่า UI

เริ่มต้นด้วยการล้าง UI เปิดไฟล์ pages/index.vue และลบโค้ดทั้งหมดที่มีดังต่อไปนี้:

 <template> <div>Hello</div> </template>

หลังจากทำเช่นนี้ คุณควรจะสามารถเห็น "สวัสดี" ในเบราว์เซอร์เท่านั้น

ในไดเร็กทอรี root ให้สร้างโฟลเดอร์ /partials ภายในโฟลเดอร์ /partials ให้สร้างไฟล์ 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 นั้นอยู่ในนั้น (นี่จะเป็นส่วนประกอบที่จะติดตั้งส่วนประกอบอื่น ๆ ทั้งหมดในแอปพลิเคชันของเรา)

หลังจากนี้ คุณควรจะสามารถเห็นสิ่งนี้ในเบราว์เซอร์ของคุณ:

คอมโพเนนต์ Nuxt.js Navbar หลังจากการปรับเปลี่ยน
คอมโพเนนต์ Nuxt.js Navbar (ตัวอย่างขนาดใหญ่)

ตอนนี้ มาตั้งค่า UI สำหรับผู้จัดการของเรากัน ในการดำเนินการนี้ เราต้องสร้างโฟลเดอร์ /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 – คุณควรเห็นสิ่งนี้:

UI ของโปรแกรมจัดการเพลง
UI ตัวจัดการเพลง (ตัวอย่างขนาดใหญ่)

รายชื่อเพลงทั้งหมด

มาต่อด้วยการสร้างฟังก์ชันที่จะดึงข้อมูลเพลงทั้งหมด ฟังก์ชันนี้จะถูกลงทะเบียนใน hook ของวงจรชีวิตที่สร้างขึ้น ดังนั้นเมื่อใดก็ตามที่สร้างส่วนประกอบขึ้น ฟังก์ชันจะถูกเรียก

เริ่มต้นด้วยการสร้างตัวแปรในอินสแตนซ์ 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 ภายในปลั๊กอินอินสแตนซ์ดังนี้:

 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 ไปยังบริการแบ็คเอนด์ของเรา หลังจากได้รับ ID เพลงจากพารามิเตอร์ฟังก์ชัน deleteMusic เราจะเพิ่ม ID ใน 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-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>

เมื่อส่งไฟล์แล้ว เพลงจะเล่นเป็นแบ็กกราวด์ จากนั้นคุณจะสามารถเห็นสิ่งนี้ในเบราว์เซอร์ของคุณ:

UI ของเครื่องเล่นเพลง
UI เครื่องเล่นเพลง (ตัวอย่างขนาดใหญ่)

หากต้องการหยุดเพลง สิ่งที่คุณต้องทำคือใส่ความคิดเห็นที่ await player.play() ในฟังก์ชัน initPlayer

การสร้าง UI ของผู้เล่น

ตอนนี้มากำหนด UI เครื่องเล่นเพลงของเราโดยแทนที่เทมเพลตในไฟล์ 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>

หลังจากแก้ไขแล้ว ผู้เล่นควรมีลักษณะดังนี้:

UI สุดท้ายของเครื่องเล่นเพลง
UI สุดท้ายของเครื่องเล่นเพลง (ตัวอย่างขนาดใหญ่)

การเพิ่มฟังก์ชั่นการเล่น

เราจะดำเนินการต่อโดยแสดงคำอธิบายเพลงบนโต๊ะ ในการดำเนินการนี้ ให้แทนที่ตารางด้วยรหัสด้านล่าง:

 <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 ได้ที่นี่
  • คุณสามารถเข้าถึงซอร์สโค้ดบน Github ได้ที่นี่