Jak zbudować menedżera muzyki za pomocą Nuxt.js i Express.js

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ W tym artykule opisano, w jaki sposób Multer usprawnia proces obsługi przesyłania plików. Wprowadza również, jak używać Mongoose do interakcji z naszą bazą danych, tworząc aplikację do zarządzania muzyką przy użyciu Express.js wraz z Multerem do przesyłania muzyki i Nuxt.js (frameworkiem Vue) dla naszego interfejsu.

Obsł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.
Więcej po skoku! Kontynuuj czytanie poniżej ↓

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:

Uruchamianie Nodemona za pomocą Terminala
Podgląd terminala (duży podgląd)

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:

Testowanie Dodawanie nowego API muzycznego za pomocą Postman
Testowanie Dodawanie nowego API muzycznego w panelu Postman (duży podgląd)

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.

Testowanie interfejsu API aukcji za pomocą Postman
Testowanie interfejsu API aukcji w panelu Postman (duży podgląd)

Usuwanie muzyki

Aby usunąć utwór muzyczny, musimy przekazać music id jako parametr.

Testowanie Usuń API za pomocą Postmana
Testowanie pulpitu nawigacyjnego Delete API Postman (duży podgląd)

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 .

Podgląd projektu Nuxt.js
Podgląd projektu Nuxt.js (duży podgląd)

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:

Komponent Nuxt.js Navbar po modyfikacji
Komponent Nuxt.js Navbar (duży podgląd)

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:

Interfejs użytkownika menedżera muzyki
Interfejs menedżera muzyki (duży podgląd)

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:

Interfejs użytkownika odtwarzacza muzyki
Interfejs odtwarzacza muzyki (duży podgląd)

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:

Ostateczny interfejs odtwarzacza muzyki
Ostateczny interfejs odtwarzacza muzyki (duży podgląd)

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