日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue3实现简易的音乐播放器组件

發布時間:2024/3/24 vue 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue3实现简易的音乐播放器组件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

用Vue3實現一個簡易的音樂播放器組件
其效果圖如下所示:

實現這個組件需要提前做的準備:

  • 引入ElementUI
  • 引入字節跳動圖標庫
  • 一張唱見圖片
  • 將要播放的音樂上傳到文件服務器上,并提供一個能在線訪問的鏈接【這里使用的是阿里云的OSS服務】

準備

ElementUI

ElementUI的引入可以參照其官網的引入方式;

字節跳動圖標庫

組件的【上一首】【播放】【下一首】【音量】等圖標都是來源自這個圖標庫,這是其安裝文檔

在main.js中,我是這樣引入的:

//引入字節跳動圖標庫 import {install} from '@icon-park/vue-next/es/all'; import '@icon-park/vue-next/styles/index.css';......//這種加載方式進行加載的話,代表使用默認的前綴進行加載:icon //也就是說假如要使用一個主頁圖標,使用圖標時標簽該這么寫: //<icon-home theme="outline" size="24" fill="#FFFFFF" :strokeWidth="2"/> //install(app,'prefix') 用這種方式進行加載的話,可以自定義使用圖標庫時的標簽前綴 install(app)

唱見圖片

音樂源

將要播放的音樂放到文件服務器上,我這里是使用阿里云的OSS服務進行音樂文件的存儲,然后在整個頁面加載時【也就是在onMounted生命周期函數中獲取這些數據源】。在后面的代碼中,這一步體現在:

//初始化歌曲源const initMusicArr = () => {requests.get("/Music/QueryAllMusic").then(function (res) {musicState.musicArr = resmusicState.musicCount = res.length})}onMounted(() => {initMusicArr()......})

完整代碼

<template><!--音樂播放器--><div class="music-container" :class="{'music-active-switch': offsetThreshold}"><div class="music-disk"><!--唱片圖片--><img class="music-disk-picture" :class="{'music-disk-playing-style': playState}" src="./images/R-C.png"alt=""></div><!--進度條--><div class="music-slider"><el-sliderv-model="playTime":format-tooltip="tooltipFormat"size="small":max="sliderLength"@change="changePlayTime"/></div><!--按鈕組--><div class="button-group"><!--上一曲 按鈕--><button class="play-button" @click="lastButtonClick"><icon-go-start theme="outline" size="23" fill="#939393" :strokeWidth="3" strokeLinejoin="miter"strokeLinecap="butt"/></button><!--播放 按鈕--><button class="play-button" @click="playButtonClick"><icon-play-one v-if="!playState" theme="outline" size="23" fill="#939393" :strokeWidth="3"strokeLinejoin="miter" strokeLinecap="butt"/><icon-pause v-if="playState" theme="outline" size="23" fill="#939393" :strokeWidth="3"strokeLinejoin="miter" strokeLinecap="butt"/></button><!--下一曲 按鈕--><button class="play-button" @click="nextButtonClick"><icon-go-end theme="outline" size="23" fill="#939393" :strokeWidth="3" strokeLinejoin="miter"strokeLinecap="butt"/></button><!--音量按鈕--><div class="voice-container"><button class="voice-button" @click="voiceButtonClick"><icon-volume-notice v-if="!voiceMute" theme="outline" size="23" fill="#939393" :strokeWidth="3"strokeLinejoin="miter" strokeLinecap="butt"/><icon-volume-mute v-if="voiceMute" theme="outline" size="23" fill="#939393" :strokeWidth="3"strokeLinejoin="miter" strokeLinecap="butt"/></button><div class="voice-slider"><el-sliderv-model="voicePower":max="1":step="0.1"size="small"@change="changeVoicePower"/></div></div></div><audioref="musicAudio"class="audio-component"controlspreload="auto"@canplay="changeDuration"><source ref="musicSource" type="audio/mpeg"/></audio></div></template><script> import {computed, onMounted, onUnmounted, reactive, ref, watch} from "vue";//這里是自己封裝的axios請求,可以將這里替換成自己的請求邏輯 import requests from "@/api/ajax";export default {name: "index",setup() {//是否正在播放const playState = ref(false);//現在的播放時間const playTime = ref(0.00);//歌曲的時間長度const playDuration = ref(0.00);//進度條長度const sliderLength = ref(100);//歌曲URLconst musicUrl = ref("");//播放器標簽const musicAudio = ref(null);//實現音樂播放的標簽const musicSource = ref(null);//是否靜音const voiceMute = ref(false);//音量大小const voicePower = ref(0.5);const musicState = reactive({musicArr: [],musicCount: 0})const musicCursor = ref(0);//頁面偏移量const pageOffset = ref(0)//是否達到閾值,達到閾值就顯示播放器,反之const offsetThreshold = ref(false)//激活播放器const operateMusicPlayer = () => {pageOffset.value = window.scrollY//當頁面滾動偏移達到800,激活用戶框if (pageOffset.value > 800) {offsetThreshold.value = true} else {//反之offsetThreshold.value = false}}//播放按鈕點擊回調const playButtonClick = () => {if (playState.value) {musicAudio.value.pause()} else {musicAudio.value.play()}//修改播放時間【設置這個,當一首歌正常播放結束之后,再次點擊播放按鈕,進度條會得到重置】playTime.value = musicAudio.value.currentTime//重新設置播放狀態playState.value = !playState.value}//上一曲按鈕點擊回調const lastButtonClick = () => {musicCursor.value -= 1changeMusic()}//下一曲按鈕點擊回調const nextButtonClick = () => {musicCursor.value += 1changeMusic()}//歌曲進度條文本提示const tooltipFormat = (val) => {let strTime = playTime.valuelet strMinute = parseInt(strTime / 60 + '')let strSecond = parseInt(strTime % 60 + '')return strMinute + ":" + strSecond}//當歌曲能播放時【亦即在canplay鉤子函數中】,musicAudio.value.duration才不會是NaN,才能進行歌曲長度的設置const changeDuration = () => {if (playDuration.value != musicAudio.value.duration) {//修改進度條的最大值sliderLength.value = musicAudio.value.duration//修改歌曲播放時間playDuration.value = musicAudio.value.duration}}//el-slider的鉤子函數,拖動進度條時快進歌曲,改變當前播放進度const changePlayTime = (val) => {musicAudio.value.currentTime = val}//音量按鈕點擊回調const voiceButtonClick = () => {voiceMute.value = !voiceMute.valueif (!voiceMute.value) {voicePower.value = 1musicAudio.value.volume = 1} else {voicePower.value = 0musicAudio.value.volume = 0}}//el-slider的鉤子函數,用于調節音量const changeVoicePower = (val) => {musicAudio.value.volume = valvoicePower.value = valif (val > 0) {voiceMute.value = false} else {voiceMute.value = true}}//播放狀態下,進度條里的數值每秒遞增。而Audio因為在播放狀態下,currentTime會自己遞增,所以不用處理const updatePlayTimePerSecond = () => {if (playState.value) {playTime.value += 1if (playTime.value >= playDuration.value) {//代表當前歌曲已經播放完畢,進行切歌musicCursor.value++changeMusic()}}}//切歌const changeMusic = () => {//切歌【這里的music_url是后端返回給前端的json字符串中,用于存儲歌曲在線鏈接的屬性名是:music_url,所以要實現自己的請求邏輯,將這里的music_url改為自己的即可】musicSource.value.src = musicState.musicArr[musicCursor.value % musicState.musicCount].music_url// 當刷新了url之后,需要執行load方法才能播放這個音樂musicAudio.value.load()playTime.value = musicAudio.value.currentTimesliderLength.value = musicAudio.value.durationmusicAudio.value.play()playState.value = true}//初始化歌曲源【將這里替換成自己的請求邏輯】const initMusicArr = () => {requests.get("/Music/QueryAllMusic").then(function (res) {musicState.musicArr = resmusicState.musicCount = res.length})}onMounted(() => {initMusicArr()//播放狀態下,使播放進度自增1,以與Audio內置的currentTime相匹配setInterval(updatePlayTimePerSecond, 1000)//添加滾動事件window.addEventListener("scroll", operateMusicPlayer)})onUnmounted(() => {window.removeEventListener("scroll", operateMusicPlayer)})return {musicAudio,musicSource,playState,playTime,playDuration,sliderLength,musicUrl,voiceMute,voicePower,musicState,musicCursor,pageOffset,offsetThreshold,playButtonClick,lastButtonClick,nextButtonClick,voiceButtonClick,tooltipFormat,changeMusic,changeDuration,changePlayTime,changeVoicePower,updatePlayTimePerSecond,initMusicArr}}, } </script><style scoped>.music-container {position: fixed;justify-content: center;width: 280px;height: 110px;background-color: white;border-radius: 15px;bottom: 15px;left: 10px;opacity: 0;transition: 0.5s; }.music-disk {position: absolute;width: 90px;height: 90px;left: 15px;top: 10px;border-radius: 50%; }.music-disk-picture {width: 90px;height: 90px;border-radius: 50%;/*設置圖片不可點擊*/pointer-events: none; }.music-disk-playing-style {animation: music-disk-rotate 5s linear infinite; }@keyframes music-disk-rotate {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);} }.button-group {position: absolute;width: 330px;height: 38px;left: 90px;bottom: 13px;margin-left: 10px; }.button-group > button {margin-left: 10px; }.play-button {float: left;width: 31px;height: 31px;padding: 4px;/*margin: 0px;*/border: 0px;border-radius: 50%;margin: 7px 0px 0px 0px; }.voice-button {float: left;width: 31px;height: 31px;padding: 0px;/*margin: 0px;*/border: 0px;border-radius: 50%;margin: 7px 0px 0px 0px;background-color: transparent; }.music-slider {position: absolute;top: 20px;left: 120px;width: 50%; }.voice-container {float: left;margin-left: 12px;width: 31px;height: 38px;overflow: hidden !important;transition: 0.5s; }.voice-container:hover {width: 160px; }.voice-slider {position: relative;top: 2px;right: -30px;width: 90px;height: 35px;background-color: white;border-radius: 10px;padding: 0px 15px 0px 15px;transition: 0.2s; }.audio-component {width: 300px;height: 200px;top: 100px;display: none; }.music-active-switch{opacity: 1; }</style>

總結

以上是生活随笔為你收集整理的Vue3实现简易的音乐播放器组件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。