Jak zbudować menedżera muzyki za pomocą Nuxt.js i Express.js
Opublikowany: 2022-03-10Obsługa cyfrowych zasobów multimedialnych, takich jak audio i wideo, w aplikacji może być trudna ze względu na kwestie, które należy uwzględnić po stronie serwera (np. sieć, pamięć masowa i asynchroniczny charakter obsługi przesyłania plików). Możemy jednak użyć bibliotek, takich jak Multer i Express.js, aby uprościć nasz przepływ pracy na zapleczu, jednocześnie korzystając z Nuxt.js (frameworka Vue) do budowania interakcji frontonu.
Za każdym razem, gdy klient WWW przesyła plik na serwer, jest on zazwyczaj przesyłany za pośrednictwem formularza i kodowany jako multipart/form-data
. Multer
to oprogramowanie pośredniczące dla Express.js i Node.js, które ułatwia obsługę tak zwanych multipart/form-data
każdym razem, gdy użytkownicy przesyłają pliki. W tym samouczku wyjaśnię, jak zbudować aplikację do zarządzania muzyką, używając Express.js z Multerem do przesyłania muzyki i Nuxt.js (framework Vue) dla naszego interfejsu.
Warunki wstępne
- Znajomość HTML, CSS i JavaScript (ES6+);
- Node.js, npm i MongoDB zainstalowane na twoim komputerze deweloperskim;
- Kod VS lub dowolny wybrany przez Ciebie edytor kodu;
- Podstawowa znajomość Express.js.
Budowanie usługi zaplecza
Zacznijmy od utworzenia katalogu dla naszego projektu, przechodząc do katalogu i wydając na terminalu npm init -y
, aby utworzyć plik package.json , który zarządza wszystkimi zależnościami dla naszej aplikacji.
mkdir serverside && cd serverside npm init -y
Następnie zainstaluj multer
, express
i inne zależności niezbędne do Bootstrapowania aplikacji Express.js.
npm install express multer nodemon mongoose cors morgan body-parser --save
Następnie utwórz plik index.js :
touch index.js
Następnie w pliku index.js zainicjujemy wszystkie moduły, stworzymy aplikację Express.js oraz stworzymy serwer do łączenia się z przeglądarkami:
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}`); });
W pierwszej kolejności wprowadzamy do projektu Express.js, a następnie definiujemy port, na którym będzie działała nasza aplikacja. Następnie wprowadzamy zależności body-parser
, morgan
, mongoose
i cors
.
Następnie zapisujemy ekspresową instancję w zmiennej o nazwie app
. Możemy użyć instancji app
do skonfigurowania oprogramowania pośredniczącego w naszej aplikacji, tak jak skonfigurowaliśmy oprogramowanie pośredniczące cors
. Używamy również instancji app
do skonfigurowania trasy głównej, która będzie działała w zdefiniowanym przez nas porcie.
Stwórzmy teraz folder /config
dla naszej config
bazy danych i konfiguracji multer
:
mkdir config and cd config touch multer.js && touch db.js
Następnie otwórz config/db.js i dodaj poniższy kod, aby skonfigurować naszą bazę danych:
module.exports = { database: "mongodb://localhost:27017/", secret: "password" };
(W rzeczywistości jest to obiekt, który przechowuje adres URL bazy danych i klucz tajny bazy danych).
Uruchomienie nodemon
i przejście do localhost:4000
w przeglądarce powinno spowodować wyświetlenie następującego komunikatu:
"Hola MEVN devs...Assemble"
Również twój terminal powinien teraz wyglądać tak:
Konfigurowanie modelu, tras i kontrolerów
Skonfigurujmy strukturę plików, wpisując:
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
W naszym terminalu używamy mkdir
, aby utworzyć nowy katalog, a następnie cd
, aby przejść do katalogu. Zaczynamy więc od utworzenia katalogu o nazwie api
, a następnie przechodzimy do katalogu api
.
Polecenie touch
służy do tworzenia nowego pliku w katalogu za pomocą terminala, podczas gdy polecenie cd
służy do wyjścia z katalogu.
Przejdźmy teraz do naszego pliku api/model/Music.js , aby utworzyć schemat muzyczny. Model to klasa, z którą konstruujemy dokumenty. W tym przypadku każdy dokument będzie utworem muzycznym o właściwościach i zachowaniach zadeklarowanych w naszym schemacie:
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;
Przejdźmy do config/multer
, aby skonfigurować 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 });
W pliku multer.js zaczynamy od utworzenia folderu, w którym zostaną przesłane wszystkie wgrane pliki muzyczne. Musimy uczynić ten plik statycznym, definiując to w pliku index.js :
app.use('/uploads', express.static('uploads'));
Następnie piszemy prosty walidator, który sprawdzi typ MIME pliku przed przesłaniem. Następnie definiujemy instancję multer
, dodając lokalizację przechowywania, limity każdego pliku i utworzony przez nas walidator.
Twórz niezbędne trasy
Teraz stwórzmy nasze trasy. Poniżej znajduje się lista punktów końcowych, które będziemy tworzyć.
HTTP POST /music | Dodaj nową muzykę |
HTTP GET /music | Pobierz całą muzykę |
HTTP DELETE /music/:blogId | Usuń muzykę |
Zacznijmy od stworzenia trasy bloga. Udaj się do api/routes/music.js i napisz następujący kod:
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;
Uwaga : Teraz za każdym razem , gdy wysyłamy żądanie do get
/music
. trasa wywołuje funkcję getAllMusic
, która znajduje się w pliku 'controllers'.
Przejdźmy do api/controllers/musicController
, aby zdefiniować kontrolery. Zaczynamy od napisania funkcji, która pobierze całą muzykę z naszej bazy danych za pomocą metody db.collection.find
mongoose, która zwróci wszystkie elementy z tej kolekcji.
Po wykonaniu tej czynności dopisujemy kolejną funkcję, która utworzy nowy utwór muzyczny w bazie danych. Musimy utworzyć nową instancję muzyki za pomocą słowa kluczowego new
, a następnie zdefiniować obiekt muzyczny. Po wykonaniu tej czynności użyjemy metody save
mangusty, aby dodać nową muzykę do bazy danych.
Aby usunąć utwór muzyczny, musimy użyć metody remove
mangoose, po prostu przekazując identyfikator muzyki jako parametr w instancji remove
. Powoduje to, że mangusta zagląda do kolekcji muzycznej, która ma ten konkretny identyfikator, a następnie usuwa ją z tej kolekcji.
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); } };
Wreszcie, aby przetestować trasy, musimy zarejestrować trasy muzyczne w naszym pliku index.js :
const userRoutes = require("./api/user/route/user"); //bring in our user routes app.use("/user", userRoutes);
Testowanie punktów końcowych
Aby przetestować nasze punkty końcowe, użyjemy POSTMAN.
Dodawanie nowej muzyki
Aby przetestować funkcję Add Music
, ustaw metodę żądania, klikając listę rozwijaną metod. Po wykonaniu tej czynności wpisz adres URL punktu końcowego, a następnie kliknij kartę treści, aby wybrać sposób wysyłania danych. (W naszym przypadku będziemy używać metody danych formularza).
Więc kliknij dane formularza i skonfiguruj klucz modelu. Podczas konfiguracji nadaj kluczom pewną wartość, jak pokazano na poniższym obrazku:
Po wykonaniu tej czynności kliknij „Wyślij”, aby złożyć wniosek.
Lista wszystkich utworów muzycznych
Aby wyświetlić całą muzykę w naszej bazie danych, musimy wpisać adres URL punktu końcowego w podanej sekcji adresu URL. Po wykonaniu tej czynności kliknij przycisk „Wyślij”, aby złożyć wniosek.
Usuwanie muzyki
Aby usunąć utwór muzyczny, musimy przekazać music id
jako parametr.
Otóż to!
Budowanie frontendu
Dla naszego frontendu użyjemy frameworka Vue: Nuxt.js.
„Nuxt to progresywny framework oparty na Vue.js do tworzenia nowoczesnych aplikacji internetowych. Opiera się na oficjalnych bibliotekach Vue.js (vue, vue-router i vuex) oraz potężnych narzędziach programistycznych (webpack, Babel i PostCSS).”
— Przewodnik NuxtJS
Aby utworzyć nową aplikację Nuxt.js, otwórz terminal i wpisz następujące polecenie (z musicapp
jako nazwą aplikacji, którą będziemy budować):
$ npx create-nuxt-app musicapp
Podczas procesu instalacji zostaną nam zadane pytania dotyczące konfiguracji projektu:
Project name | aplikacja muzyczna |
project description | Prosta aplikacja do zarządzania muzyką |
Author name | <twoje imię> |
Package manager | npm |
UI framework | Bootstrap vue |
custom ui framework | Żaden |
Nuxt modules | Axios,pwa (użyj spacji na klawiaturze, aby wybrać elementy) |
Linting tool | Ładniejsze |
test framework | Nic |
Rendering Mode | Uniwersalny (SSR) |
development tool | Jsonconfig.json |
Po zaznaczeniu tego wszystkiego musimy chwilę poczekać na skonfigurowanie projektu. Gdy będzie gotowy, przejdź do folderu /project
i obsługuj projekt w następujący sposób:
cd musicapp && npm run dev
Otwórz projekt w dowolnym edytorze kodu, a następnie otwórz projekt w przeglądarce, uzyskując dostęp do localhost:3000
.
Konfiguracja Axios
Będziemy używać axios
do wysłania żądania HTTP do naszego serwera zaplecza. Axios jest już zainstalowany w naszym projekcie, więc wystarczy skonfigurować baseURL
- do naszego serwera zaplecza.
Aby to zrobić, otwórz plik nuxt.config.js w katalogu root
i dodaj baseURL
w obiekcie axios
.
axios: { baseURL:'https://localhost:4000' },
Budowanie menedżera muzyki
Konfiguracja interfejsu użytkownika
Zacznijmy od uporządkowania interfejsu użytkownika. Otwórz plik pages/index.vue i usuń cały zawarty w nim kod, wykonując następujące czynności:
<template> <div>Hello</div> </template>
Po wykonaniu tej czynności powinieneś widzieć tylko „Hello” w przeglądarce.
W katalogu root
utwórz folder /partials
. W folderze /partials
partials utwórz plik navbar.vue i dodaj następujący kod:
<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>
Uwaga : będziemy używać tego komponentu do poruszania się po stronach w naszej aplikacji. Będzie to po prostu prosty komponent złożony z paska nawigacyjnego Bootstrap navbar
Sprawdź oficjalną dokumentację Bootstrap, aby uzyskać więcej informacji.
Następnie zdefiniujmy niestandardowy układ aplikacji. Otwórz folder /layouts
, zastąp kod w pliku default.vue poniższym kodem.
<template> <div> <navbar /> <nuxt /> </div> </template> <script> import navbar from '@/partial/navbar' export default { components: { navbar } } </script>
Importujemy navbar
do tego układu, co oznacza, że wszystkie strony w naszej aplikacji będą zawierały ten składnik navbar
. (Będzie to komponent, do którego zostaną zamontowane wszystkie inne komponenty w naszej aplikacji.)
Po tym powinieneś być w stanie zobaczyć to w swojej przeglądarce:
Teraz skonfigurujmy interfejs użytkownika dla naszego menedżera. Aby to zrobić, musimy utworzyć folder /manager
w folderze components, a następnie dodać plik do folderu o nazwie manager.vue .
W tym pliku dodaj następujący kod:
<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>
Uwaga : to jest tylko prosty szablon Bootstrap do dodawania muzyki do naszej aplikacji. W formularzu zdefiniowany zostanie szablon tabeli, w którym wyszczególnione zostaną wszystkie utwory muzyczne, jakie można znaleźć w naszej bazie danych.
Po zdefiniowaniu tego komponentu musimy zarejestrować go w folderze /pages
, aby zainicjować routing.
Nuxt.js nie ma pliku „router.js”, takiego jak Vue.js. Używa folderu stron do routingu. Aby uzyskać więcej informacji, odwiedź witrynę Nuxt.js.
Aby zarejestrować komponent, utwórz folder /manager
w folderze /pages
i utwórz plik index.vue . Następnie umieść w pliku następujący kod:
<template> <div> <manager /> </div> </template> <script> import manager from '@/components/manager/manager' export default { components: { manager } } </script>
Jest to komponent, który wyrenderuje trasę na naszych pages
.
Po wykonaniu tej czynności przejdź do przeglądarki i przejdź do /manager
— powinieneś zobaczyć to:
Lista wszystkich utworów muzycznych
Kontynuujmy tworzenie funkcji, która pobierze całą muzykę. Ta funkcja zostanie zarejestrowana w utworzonym haku cyklu życia, dzięki czemu za każdym razem, gdy tworzony jest komponent, funkcja zostanie wywołana.
Zacznijmy od utworzenia zmiennej w instancji vue
, która będzie przechowywać całą muzykę:
allmusic = []; musicLoading: false,
Następnie zdefiniuj funkcję getAllMusics
i dodaj następujący kod:
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') } }
Następnie zarejestruj się w utworzonym haku cyklu życia:
created() { this.getAllMusics() }
Wyprowadzanie danych
Teraz nadszedł czas na wypisanie wszystkich utworów na stole, które stworzyliśmy wcześniej:
<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>
Pamiętasz ten stół, który stworzyliśmy wcześniej? Cóż, będziemy musieli zapętlić odpowiedź otrzymaną z naszego zaplecza, aby wyświetlić całą muzykę otrzymaną z bazy danych.
Dodawanie muzyki
Aby dodać nowy utwór muzyczny, musimy wysłać żądanie HTTP do serwera zaplecza ze szczegółami muzyki. W tym celu zacznijmy od modyfikacji formy i obsługi przesyłania plików.
W formularzu musimy dodać detektor event
, który będzie nasłuchiwał formularza po jego przesłaniu. W polu input
dodajemy model v-
, aby powiązać wartość z polem wejściowym.
<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>
A sekcja skryptu powinna wyglądać tak:
<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>
Zdefiniujemy funkcję, która wyśle żądanie do naszego serwisu zaplecza, aby utworzyć nową muzykę, która została dodana do listy. Również. musimy napisać prostą funkcję walidacji, która sprawdzi typ pliku, aby użytkownicy mogli przesyłać tylko pliki z rozszerzeniami .mp3 i .mp4 .
Ważne jest, aby zdefiniować obliczoną właściwość, aby upewnić się, że nasze pole wejściowe nie jest puste. Musimy również dodać prosty walidator, który upewni się, że plik, który próbujemy przesłać, jest rzeczywiście plikiem muzycznym.
Kontynuujmy edycję funkcji addMusic
, aby wysłać żądanie do naszej usługi zaplecza. Ale zanim to zrobimy, zainstalujmy najpierw sweetalert
, który zapewni nam ładne okno modalne. Aby to zrobić, otwórz terminal i wpisz:
npm i sweetalert
Po zainstalowaniu pakietu utwórz plik sweetalert.js w folderze /plugins
i dodaj to:
import Vue from 'vue'; import swal from 'sweetalert'; Vue.prototype.$swal = swal;
Następnie zarejestruj wtyczkę w pliku nuxt.config.js wewnątrz instancji wtyczki w następujący sposób:
plugins: [ { src: '~/plugins/sweetalert' } ],
Teraz pomyślnie skonfigurowaliśmy sweetalert
w naszej aplikacji, więc możemy przejść dalej i edytować funkcję addmusic
do tego:
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 } },
Napiszmy prosty skrypt, który będzie przełączał formę, tzn. powinien wyświetlać się tylko wtedy, gdy chcemy dodać nową muzykę.
Możemy to zrobić, edytując przycisk „Dodaj muzykę” w tabeli, która wyświetla całą muzykę, którą można znaleźć:
<button class="btn btn-info m-3" @click="initForm"> {{addState?"Cancel":"Add New Music"}} </button>
Następnie dodaj stan, który będzie zawierał stan formularza we właściwości data
:
addState: false
Po wykonaniu tej czynności zdefiniujmy funkcję initForm
:
initForm() { this.addState = !this.addState },
A następnie dodaj v-if="addState"
do elementu div
, który przechowuje formularz:
<div class="card" v-if="addState">
Usuwanie muzyki
Aby usunąć muzykę, musimy wywołać punkt końcowy delete
i przekazać music id
jako parametr. Dodajmy zdarzenie click
do przycisku „Usuń”, które spowoduje wyzwolenie funkcji w celu usunięcia funkcji:
<button class="btn btn-info" @click="deleteMusic(music._id)">Delete</button>
Funkcja delete
będzie wysyłała żądanie HTTP do naszej usługi zaplecza. Po uzyskaniu identyfikatora muzyki z parametru funkcji deleteMusic
, dodamy identyfikator w adresie URL, którego używamy do wysłania żądania. Określa dokładny utwór muzyczny, który powinien zostać usunięty z bazy danych.
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!') } }) }
Z tym wszystkim właśnie zbudowaliśmy naszego menedżera muzycznego. Teraz nadszedł czas na zbudowanie odtwarzacza muzycznego.
Zacznijmy od utworzenia nowego folderu w folderze components o nazwie /player
. Następnie utwórz plik player.vue w tym folderze i dodaj to:
<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>
Następnie zaimportujmy ten komponent do pliku index.vue w folderze /pages
. Zastąp kod w pliku index.vue następującym:
<template> <div> <player /> </div> </template> <script> import player from '@/components/player/player' export default { components: { player } } </script>
Skonfigurujmy routing w naszym komponencie navbar
, aby umożliwić routing między naszymi stronami.
Do trasowania w aplikacji nuxt-link
, po którym określasz stronę dla tej trasy do określonej instancji. Zmodyfikujmy więc kod w komponencie partials/navbar
do tego:
<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>
Dzięki temu możemy poruszać się po naszych stronach za pomocą paska nawigacyjnego.
Budowanie gracza
Zanim zaczniemy, musimy rozszerzyć Webpack, aby załadować pliki audio. Pliki audio powinny być przetwarzane przez file-loader
. Ten program ładujący jest już zawarty w domyślnej konfiguracji Webpacka, ale nie jest skonfigurowany do obsługi plików audio.
Aby to zrobić, przejdź do pliku nuxt.config.js i zmodyfikuj obiekt build
do tego:
build: { extend(config, ctx) { config.module.rules.push({ test: /\.(ogg|mp3|mp4|wav|mpe?g)$/i, loader: 'file-loader', options: { name: '\[path\][name].[ext]' } }) } }
Następnie napiszmy funkcję, która pobierze wszystkie utwory, a następnie użyjmy konstruktora Audio
do odtworzenia pierwszego utworu w tablicy allMusic
.
Na początek zmodyfikujmy nasz plik player.vue do tego:
<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>
Po udostępnieniu pliku muzyka będzie odtwarzana w tle, a następnie powinieneś być w stanie zobaczyć to w swojej przeglądarce:
Aby zatrzymać muzykę, wystarczy skomentować await player.play()
w funkcji initPlayer
.
Tworzenie interfejsu gracza
Zdefiniujmy teraz nasz interfejs odtwarzacza muzyki, zastępując szablon w naszym pliku player.vue następującym:
<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>
Następnie dodaj następujący styl do sekcji 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>
Po modyfikacji gracz powinien wyglądać tak:
Dodawanie funkcji odtwarzania
Kontynuujemy, wyświetlając opis muzyki na stole. W tym celu zastąp tabelę poniższym kodem:
<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>
Nie chcemy jednocześnie wyświetlać ikon „Odtwórz” i „Wstrzymaj”. Zamiast tego chcemy sytuacji, w której podczas odtwarzania utworu wyświetlana jest ikona „Wstrzymaj”. Ponadto, gdy utwór jest wstrzymany, powinna zostać wyświetlona ikona odtwarzania.
Aby to osiągnąć, musimy ustawić stan isPlaying
na false
instancję, a następnie użyć tej instancji do przełączania ikon. Następnie dodamy funkcję do naszej ikony „Odtwórz”.
isplaying:false
Po wykonaniu tej czynności zmień ikonę „Odtwórz” i „Wstrzymaj” na:
<i class="fas fa-play play" v-if="!isplaying" @click="play"></i> <i class="fas fa-pause play" v-else></i>
Z tym wszystkim zdefiniujmy metodę 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 },
Przede wszystkim pobieramy aktualną piosenkę i przekazujemy ją do parametru function
. Następnie definiujemy instancję JavaScript Audio()
. Następnie sprawdzamy, czy utwór ma wartość null: Jeśli tak nie jest, ustawiamy this.current
na utwór, który przekazaliśmy w parametrze, a następnie wywołujemy instancję odtwarzacza Audio
. (Nie zapominaj też, że podczas odtwarzania muzyki musimy ustawić stan isPlaying
na true
).
Dodawanie funkcji pauzy
Aby wstrzymać utwór, użyjemy metody pauzy Audio
. Musimy dodać zdarzenie click
do ikony pauzy:
<i class="fas fa-pause play" @click="pause" v-else></i>
A następnie zdefiniuj funkcję w instancji methods
:
pause() { this.player.pause() this.isplaying = false },
Odtwarzanie utworu z listy muzyki
Jest to dość proste do zaimplementowania. Wszystko, co musimy zrobić, to dodać zdarzenie click
, które zmieni parametr song
w metodzie play
na utwór, który właśnie stworzyliśmy.
Po prostu zmień przycisk play
w tabeli listy muzyki na:
<button class="btn btn-primary" @click="play(music)">Play</button>
I masz to!
Dodawanie następnej funkcji
Aby dodać kolejną funkcję, musimy zwiększyć indeks o jeden. Aby to zrobić, dodaj zdarzenie click
do następnej ikony:
@click="next"
A następnie zdefiniuj funkcję prev
w instancji methods
:
next() { this.index++ if (this.index > this.allMusic.length - 1) { this.index = 0 } this.current = this.allMusic[this.index] this.play(this.current) },
Ten warunek jest odpowiedzialny za ponowne odtworzenie wszystkich utworów po odtworzeniu ostatniego utworu z listy.
Dodawanie previous
funkcji
W rzeczywistości jest to przeciwieństwo następnej funkcji, więc dodajmy zdarzenie click
do poprzedniej funkcji:
@click="prev"
Następnie definiujemy poprzednią funkcję:
prev() { this.index-- if (this.index < 0) { this.index = this.allMusic.length - 1 } this.current = this.allMusic[this.index] this.play(this.current) },
Nasza aplikacja odtwarzacza muzyki jest już gotowa!
Wniosek
W tym artykule przyjrzeliśmy się, jak możemy zbudować menedżera muzyki za pomocą Nuxt.js i Express.js. Po drodze widzieliśmy, jak Multer usprawnia proces obsługi przesyłania plików i jak używać Mongoose do interakcji bez bazy danych. Wreszcie, użyliśmy Nuxt.js do zbudowania aplikacji klienckiej, która zapewnia jej szybką i zgrabną atmosferę.
W przeciwieństwie do innych frameworków, budowanie aplikacji za pomocą Nuxt.js i Express.js jest dość łatwe i szybkie. Fajną częścią Nuxt.js jest sposób, w jaki zarządza on Twoimi trasami i umożliwia lepszą strukturę aplikacji.
- Więcej informacji o Nuxt.js znajdziesz tutaj.
- Możesz uzyskać dostęp do kodu źródłowego na Github tutaj