如何使用 Nuxt.js 和 Express.js 構建音樂管理器

已發表: 2022-03-10
快速總結↬本文介紹 Multer 如何簡化處理文件上傳的過程。 它還介紹瞭如何使用 Mongoose 與我們的數據庫進行交互,方法是使用 Express.js 和 Multer 構建音樂管理器應用程序用於音樂上傳和 Nuxt.js(Vue 框架)用於我們的前端。

在您的應用程序中處理數字媒體資產(例如音頻和視頻)可能會很棘手,因為必須考慮到服務器端(例如網絡、存儲和處理文件上傳的異步性質)。 但是,我們可以使用 Multer 和 Express.js 等庫來簡化後端的工作流程,同時使用 Nuxt.js(Vue 框架)來構建前端交互。

每當 Web 客戶端將文件上傳到服務器時,它通常通過表單提交並編碼為multipart/form-dataMulter是 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

接下來,安裝multerexpress和引導 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-parsermorganmongoosecors依賴項。

然後我們將 express 實例保存在一個名為app的變量中。 我們可以使用app實例在我們的應用程序中配置中間件,就像我們配置cors中間件一樣。 我們還使用app實例來設置將在我們定義的端口中運行的根路由。

現在讓我們為我們的數據庫configmulter配置創建一個/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
終端預覽(大預覽)

設置模型、路由和控制器

讓我們通過鍵入以下內容來設置文件結構:

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

之後,我們編寫了一個簡單的驗證器,它將在上傳之前檢查文件的mimetype 。 然後,我們通過添加存儲位置、每個文件的限制以及我們創建的驗證器來定義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;

注意現在每當我們/music發出get請求時 該路由調用位於“控制器”文件中getAllMusic函數。

讓我們轉到api/controllers/musicController來定義控制器。 我們首先編寫一個函數,使用 mongoose db.collection.find方法獲取數據庫中的所有音樂,該方法將返回該集合中的所有項目。

之後,我們編寫另一個函數,將在數據庫中創建一段新音樂。 我們需要使用new關鍵字創建一個新的音樂實例,然後定義音樂對象。 完成此操作後,我們將使用 mongoose save方法將新音樂添加到數據庫中。

為了刪除一首音樂,我們需要使用 mongoose 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 方法。)

因此,單擊表單數據並設置您的模型密鑰。 當你設置它時,給鍵一些值,如下圖所示:

測試使用 Postman 添加新的音樂 API
測試在 Postman 儀表板中添加新的音樂 API(大預覽)

完成此操作後,單擊“發送”以發出請求。

列出所有音樂

要列出我們數據庫中的所有音樂,我們必須在提供的 URL 部分中鍵入端點 URL。 完成此操作後,單擊“發送”按鈕發出請求。

使用 Postman 測試列表 API
在 Postman 儀表板中測試列表 API(大預覽)

刪除音樂

要刪除一段音樂,我們需要將music id作為參數傳遞。

使用 Postman 測試刪除 API
測試刪除 API Postman 儀表板(大預覽)

而已!

構建前端

對於我們的前端,我們將使用 Vue 框架:Nuxt.js。

“Nuxt 是一個基於 Vue.js 的漸進式框架,用於創建現代 Web 應用程序。 它基於 Vue.js 官方庫(vue、vue-router 和 vuex)和強大的開發工具(webpack、Babel 和 PostCSS)。”

— NuxtJS 指南

要創建一個新的 Nuxt.js 應用程序,請打開您的終端並輸入以下內容( musicapp作為我們將要構建的應用程序的名稱):

 $ npx create-nuxt-app musicapp

在安裝過程中,我們會被問到一些關於項目設置的問題:

Project name 音樂應用
project description 一個簡單的音樂管理器應用
Author name <你的名字>
Package manager npm
UI framework 引導程序
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 - 到我們的後端服務器。

為此,請打開root目錄中的nuxt.config.js文件,並將 baseURL 添加到baseURLaxios中。

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

構建音樂管理器

設置用戶界面

讓我們從清理 UI 開始。 打開pages/index.vue文件並使用以下內容刪除其中的所有代碼:

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

完成此操作後,您應該只能在瀏覽器中看到“Hello”。

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 導航欄組件(大預覽)

現在讓我們為我們的經理設置 UI。 為此,我們需要在 components 文件夾中創建一個/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>

注意這只是一個簡單的引導模板,用於將音樂添加到我們的應用程序中。 該表單將定義一個表格模板,該模板將列出可以在我們的數據庫中找到的所有音樂。

定義好這個組件後,我們需要在/pages文件夾中註冊它來初始化路由。

Nuxt.js 沒有像 Vue.js 這樣的“router.js”文件。 它使用 pages 文件夾進行路由。 有關更多詳細信息,請訪問 Nuxt.js 網站。

要註冊組件,請在/pages文件夾中創建一個/manager文件夾並創建一個index.vue文件。 然後,將以下代碼放入文件中:

 <template> <div> <manager /> </div> </template> <script> import manager from '@/components/manager/manager' export default { components: { manager } } </script>

這是將在我們的pages路由中呈現的組件。

完成此操作後,轉到您的瀏覽器並導航到/manager您應該會看到以下內容:

音樂管理器界面
音樂管理器 UI(大預覽)

列出所有音樂

讓我們繼續創建一個可以獲取所有音樂的函數。 該函數將註冊在 created 生命週期鉤子中,以便每當創建組件時,都會調用該函數。

讓我們首先在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- -model 以將值綁定到輸入字段。

 <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

安裝包後,在/plugins文件夾中創建一個sweetalert.js文件並添加:

 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 請求。 從deleteMusic函數參數中獲取音樂 ID 後,我們將在用於發送請求的 URL 中添加該 ID。 這指定了應該從數據庫中刪除的確切音樂片段。

 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>

接下來,讓我們將這個組件導入到/pages文件夾中的index.vue文件中。 將index.vue文件中的代碼替換為:

 <template> <div> <player /> </div> </template> <script> import player from '@/components/player/player' export default { components: { player } } </script>

讓我們在navbar組件中配置路由以啟用頁面之間的路由。

要在 Nuxt.js 應用程序中進行路由,使用nuxt-link之後,您已經指定了該路由到特定實例的頁面。 因此,讓我們將partials/navbar組件中的代碼編輯為:

 <template> <header> <nav class="navbar navbar-expand-lg navbar-light bg-info"> <div class="container"> <nuxt-link to="/" class="navbar-brand">Music App</nuxt-link> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation" > <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse justify-content-end"> <ul class="navbar-nav"> <li class="nav-item active"> <nuxt-link to="/" class="nav-link">Player</nuxt-link> </li> <li class="nav-item"> <nuxt-link to="/manager" class="nav-link">Manager</nuxt-link> </li> </ul> </div> </div> </nav> </header> </template> <style scoped> .nav-link, .navbar-brand { color: #ffff !important; } </style>

有了這個,我們可以使用導航欄瀏覽我們的頁面。

構建播放器

在開始之前,我們需要擴展 Webpack 來加載音頻文件。 音頻文件應由file-loader處理。 此加載器已包含在默認 Webpack 配置中,但未設置為處理音頻文件。

為此,請轉到nuxt.config.js文件並將build對象修改為:

 build: { extend(config, ctx) { config.module.rules.push({ test: /\.(ogg|mp3|mp4|wav|mpe?g)$/i, loader: 'file-loader', options: { name: '\[path\][name].[ext]' } }) } }

接下來,讓我們編寫一個函數來獲取所有歌曲,然後使用Audio構造函數播放allMusic數組中的第一首歌曲。

對於初學者,讓我們將 player.vue文件修改為:

 <template> <section v-if="allMusic"> <div class="container"> <div class="row"> <div class="col-md-12"> <h3 class="text-center">Player</h3> </div> </div> <div class="row"> <div class="col-md-6"> <span>{{this.current.title}} - {{this.current.artist}}</span> </div> </div> </div> </section> </template> <script> export default { data() { return { current: { title: '', artist: '' }, song: true, isplaying: false, allMusic: null, index: 0, player: '' } }, methods: { async initPlayer() { if (this.allMusic !== []) { this.current = await this.allMusic[this.index] this.player.src = `https://localhost:4000/${this.current.music.path}` } else { this.song = true } }, async getAllSongs() { try { let response = await this.$axios.$get('/music') console.log(response) if (response === []) { this.song = true this.current = null } else { this.song = false this.allMusic = response } await this.initPlayer() } catch (err) { this.current = null console.log(err) } } }, created() { if (process.client) { this.player = new Audio() } this.getAllSongs() } } </script> <style scoped> </style>

提供文件後,音樂將在後台播放,然後您應該能夠在瀏覽器中看到:

音樂播放器界面
音樂播放器 UI(大預覽)

要停止播放音樂,您只需在initPlayer函數中註釋掉await player.play()即可。

創建播放器 UI

現在讓我們通過將player.vue文件中的模板替換為以下內容來定義我們的音樂播放器 UI:

 <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
音樂播放器的最終用戶界面(大預覽)

添加播放功能

我們將繼續在桌子上顯示音樂描述。 為此,請將表格替換為以下代碼:

 <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事件,它將play方法中的song參數更改為我們剛剛創建的歌曲。

只需將音樂列表表上的play按鈕修改為:

 <button class="btn btn-primary" @click="play(music)">Play</button>

你有它!

添加下一個函數

要添加下一個函數,我們需要將索引加一。 為此,請在下一個圖標中添加一個click事件:

 @click="next"

然後在methods實例中定義prev函數:

 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 上的源代碼