国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

用Vue搭建一個應用盒子(三):音樂播放器

appetizerio / 2603人閱讀

摘要:組件結構接著我們就該搭建這個播放器的組件了。總的原理是首先獲取音頻的持續時間,然后通過一個定時器,不斷更新顯示時間,播放完成時,計時器停止。這個頁面比較簡單,播放器標簽,綁定了事件,即播放完成后執行。

這個播放器的開發歷時2個多月,并不是說它有多復雜,相反它的功能還非常不完善,僅具雛形。之所以磨磨蹭蹭這么久,一是因為拖延,二也是實習公司項目太緊。8月底結束實習前寫完了樣式,之后在家空閑時間多了,集中精力就把JS部分做完了。

這個播放器確實比當初構想的復雜,開始只打算做一個搜歌播放的功能。現在做出來的這個播放器,可以獲取熱門歌曲,可以搜歌,可以調整播放進度條,功能確實完善不少。

這次完成這個項目也是收獲頗豐,點了不少新的技能點,當然,這個簡陋的小項目也挖了不少坑,不知道啥時候能填上……

話不多說,看代碼吧。

Muse-ui

不記得在哪個網站看到這個組件庫的了,覺得好酷炫,于是用起來~

這是官網:地址

使用這個組件庫的原因除了漂亮,還因為這是基于Vue 2.0,無縫對接,方便。

使用方法跟之前的插件一樣,npm安裝:

npm install --save muse-ui

安裝好后,在main.js中注冊。

import MuseUi from "muse-ui"
import "muse-ui/dist/muse-ui.css"
import "muse-ui/dist/theme-light.css"

Vue.use(MuseUi)

就可以在項目中使用了。
PS:Muse-ui的icon是基于谷歌的Material icons,大家可以根據自己的需求到官網找icon的代碼。

組件結構

接著我們就該搭建這個播放器的組件了。

結構如下:

||-- player.vue       // 主頁面
|    |-- playerBox.vue   // 播放器組件
|    |-- popular.vue    // 熱門歌曲頁面
|        |-- songList.vue     // 歌曲列表頁面 
|    |-- play.vue    // 播放器頁面
|    |-- search.vue    // 搜索頁面

PS:熱門歌曲、搜索頁面都能進入歌曲列表頁面,播放器組件playerBox.vue 是放標簽的組件,是功能性組件。

我們來分別敘述:

1.player.vue

直接看代碼吧:




  

解釋一下:

由于Muse-ui有部分樣式用到了less,所以在這里我們需要npm安裝一個less的依賴,安裝好后即可使用。

npm install less less-loader --save

這里我們加載了一個底部導航,muse-ui的,官網可以查到相關代碼。這里要注意的是,為了讓用戶體驗更好,我們需要讓我們的底部導航隨當前路由變化而高亮。具體是用了一段JS代碼。

watch監視路由變化并觸發一個method:changebar(),這個函數會獲取當前的路由名,并把bottomNav的值設置為當前路由名——即高亮當前的路由頁面

playerBox.vue組件之所以放在主組件里,就是為了音樂在每一個子頁面都能播放,而不會因為跳轉路由而停止播放。

2.popular.vue

這是推薦歌單界面,這里用到了一個輪播圖插件,是基于vue的,使用起來比較方便,直接用npm安裝:

npm install vue-awesome-swiper --save

安裝好后,同樣在main.js中注冊:

import VueAwesomeSwiper from "vue-awesome-swiper"

Vue.use(VueAwesomeSwiper)

然后我們來看頁面的代碼:




  

這里要說明一下,上面的這些組件除了playerBox之外都要在main.js中注冊才能使用。注冊方法忘記的了話,回頭看看我之前寫的todolist的項目是怎么注冊的。

store.js中添加playList函數:

playlist(state,id){
        const url="http://localhost:3000/playlist/detail?id="+id;
        axios.get(url).then(res=> {
            state.playlist=res.data.playlist;
        })
    },

這里的頁面mu開頭的基本都是用Muse-ui搭建起來的,Swiper開頭的則是輪播圖插件。界面不復雜,主要是三個部分,上面的輪播圖,中間的熱門歌單推薦,底部的版權信息。樣式基本是模板,這里做了一個簡單的移動端適配:在PC端歌單會以每排4個分兩排的形式排列,在移動端歌單則會以每排2個分四排的形式排列,適配的方法是媒體查詢,通過改變歌單div的寬度改變每行歌單的數目。

這里要注意的:

歌單的數據和輪播圖都是用的網易云數據,所以沒有開api是無法讀取的,引入axios的部分可以先不寫,也可以寫好先放著。

這里methodscreated里面的內容都涉及到axios的請求,所以可以先不寫,不影響樣式呈現。數據可以先用假數據代替。

playList的目的是點擊歌單的時候,進入歌單詳情頁,同時根據傳遞進去的歌單id獲取歌單的具體數據,axios的地址是api的地址,需要加載api插件才能使用。

3.play.vue

終于到了最核心的組件,之所以說它核心是因為這是播放界面,音頻播放的長度、音頻信息都會在這里被呈現,而播放器的核心功能——播放——也是在這里被操作(播放/暫停)。

看具體代碼:




  


store.js添加代碼:

 play(state){
        clearInterval(ctime);
        const playerBar=document.getElementById("playerBar");
        const eve=$(".addPlus i")[0];
        
        
        let currentTime=playerBar.currentTime;
        let currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);
        let duraTime=playerBar.duration;
        let duraMinute=Math.floor(duraTime/60)+":"+(duraTime%60/100).toFixed(2).slice(-2);
        state.audio.progressPercent=((playerBar.currentTime/playerBar.duration)*100).toFixed(1);
        
        if(playerBar.paused){
            playerBar.play();
            eve.innerHTML="pause";
            state.audio.duration=duraMinute;
            state.audio.currentTime=currentMinute;
            ctime=setInterval(
                function(){
                    
                    currentTime++;
                    
                    currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);
                    
                    state.audio.currentTime=currentMinute;
                    state.audio.progressPercent=((playerBar.currentTime/playerBar.duration)*100).toFixed(1);
                    
                },1000
            )
        }else {
            playerBar.pause();
            eve.innerHTML="play_arrow";
            clearInterval(ctime);
        }
               
        
    },

    audioEnd(state){
        
        const playerBar=document.getElementById("playerBar");
        const eve=$(".addPlus i")[0];

        eve.innerHTML="play_arrow";
        clearInterval(ctime);

        
        playerBar.currentTime=0;

        let currentTime=playerBar.currentTime;
        let currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);
        state.audio.currentTime=currentMinute;
    },

    editProgress(state,progressValue){
        const playerBar=document.getElementById("playerBar");
        const eve=$(".addPlus i")[0];

        let duraTime=playerBar.duration;
        let duraMinute=Math.floor(duraTime/60)+":"+(duraTime%60/100).toFixed(2).slice(-2);
        // console.log(progressValue);
        clearInterval(ctime);
        if(playerBar.paused){
            playerBar.play();
            eve.innerHTML="pause"
            state.audio.duration=duraMinute;
        }
        let currentTime=playerBar.duration*(progressValue/100);
        
        
        ctime=setInterval(
            function(){
                
                currentTime++;
                
                currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);
                
                state.audio.currentTime=currentMinute;
                state.audio.progressPercent=((playerBar.currentTime/playerBar.duration)*100).toFixed(1);
                
            },1000
        )

        playerBar.currentTime=currentTime;
        
        let currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);

        state.audio.currentTime=currentMinute;
    },

如代碼所示,我在頂部導航添加了一個icon button,樣式來自Muse-ui綁定了一個點擊事件backpage,點擊后會回到上一個路由頁面。這個需要配合之前的高亮底部導航icon,才能實現返回上一路由的同時高亮相對應的icon。

還要注意的是,computed里有兩個方法,第一個是獲取vuex里面的當前曲目信息;第二個則是獲取進度條的百分比信息,這個方法實現了數據的雙向綁定,隨著后臺設定的計時器,不斷地更新,從而實現播放時進度條的變化。同樣,這里的樣式也是來自Muse-uiSlider

這里有一個需要注意的坑是,Muse-ui自帶了許多的函數,第一次寫的時候沒有注意,在進度條上綁定了一個mouseup事件,結果無效,后來才發現,其實已經自帶了change事件,還可以實現移動端的兼容。所以寫代碼的時候一定要多看看官網文檔。

關于store.js里的方法,play是播放/暫停,具體會根據當前音頻文件的paused(即是否暫停)來判斷。總的原理是首先獲取音頻的持續時間,然后通過一個定時器,不斷更新顯示時間,播放完成時,計時器停止。

計時器很關鍵,進度條和顯示時間的更新都需要它。但是計時器有個坑,如果把計時器聲明放在play方法里,則無法在audioEnd方法里停止計時器,所以這里我們需要在最外層先聲明一個ctime,然后再在play方法里把定時器賦值給ctime,這樣我們就可以隨時停止計時器了。

audioEnd方法是播放停止時要做的事情,我們會把停止按鈕切換成播放,把顯示時間修改掉,別忘了停止計時器。

editProgress方法是點擊或拖動進度條時做的事情,我們會改變當前音頻的currentTime,即當前時間,如果音頻是暫停狀態,我們要讓它繼續播放。

4.search.vue

這也是一個比較核心的一個功能,畢竟推薦的歌單只有幾個。看代碼:




  


store.js里添加:

getSearch(state,value){
        const url="http://localhost:3000/search?keywords="+value+"?limit=30";
        axios.get(url).then(res=>{
            state.result=res.data.result;
        })
        
    },
    getSong(state,{id,name,singer,album,arid}){
        const url="http://localhost:3000/music/url?id="+id;
        const imgUrl="http://localhost:3000/artist/album?id="+arid;
        const playerBar=document.getElementById("playerBar");
        

        axios.get(url).then(res=>{
            
            state.audio.location=res.data.data[0].url;
            state.audio.flag=res.data.data[0].flag;
            
            state.audio.songName=name;
            state.audio.singer=singer;
            state.audio.album=album;
        })
        axios.get(imgUrl).then(res=>{
            state.audio.picUrl=res.data.artist.picUrl;
        })
        
        let currentTime=playerBar.currentTime;
        let currentMinute=Math.floor(currentTime/60)+":"+(currentTime%60/100).toFixed(2).slice(-2);
        let duraTime=playerBar.duration;
        let duraMinute=Math.floor(duraTime/60)+":"+(duraTime%60/100).toFixed(2).slice(-2);

        state.audio.duration=duraMinute;
        state.audio.currentTime=currentMinute;
        state.audio.progressPercent=((playerBar.currentTime/playerBar.duration)*100).toFixed(1);
        
        
    }
注意,在有需要使用axios的組件一定要import,npm下載安裝不用多說了。

解釋一下這個組件的兩個方法:

getSearch是獲取搜索結果,它被綁定再搜索按鈕上,初始頁面是空白,通過傳遞關鍵字,用axios從api獲取搜索結果,再把結果顯示在頁面上。

getSong綁定在每一個搜索的結果上,有兩個步驟,第一是getSong,會把點擊的歌曲設置為要播放的歌曲,并把相關信息傳遞給play.vue,讓它顯示在相應的地方;第二個步驟,會播放歌曲,也就是上面的play方法,具體不必再說。

這里有一個坑,我們可能需要通過vuex傳遞參數,但是有時候傳遞多個參數會出現undefined的情況,這時候我們要把參數們寫成{參數一,參數二,參數三}的形式。

5.songList

這個組件主要是歌單詳情頁,基本的樣式和搜索頁一樣,就是獲取歌單的內容不同,搜索頁面的列表是根據關鍵詞獲取的,歌單詳情頁的列表是根據歌單id獲取的,獲取的方式都是通過axios。




  

沒什么需要解釋的,注意我們在getSong里面傳遞的多個參數。

6.playerBox.vue



  

這個頁面比較簡單,播放器audio標簽,綁定了ended事件,即播放完成后執行。
這里有一個坑,解釋一下:我把播放器按鈕放在這里了,為什么呢?之前我是放在play.vue里的,但是我發現一個問題,就是通過點擊歌單的歌曲播放時,無法改變播放/暫停按鈕,為什么呢?因為我改變按鈕的方法是用innerHTML改變,我為什么要用這種方法呢?因為Muse-ui的icon經過渲染,是以標簽的值的形式出現的。這就不得不獲取DOM了,但是如果把按鈕寫在play.vue里,在歌單頁面時是獲取不到指定DOM的,因為當前頁面根本沒有這個DOM!只有把按鈕寫在在主組件里的playerBox.vue里,才能獲取到指定DOM。

但是寫在playBox.vue里又有一個問題,按鈕會出現在每一個頁面里,但是我們只要它出現在播放頁面就好了,所以我們在這里要給按鈕綁定一個v-show,里面的內容就是判斷是不是在指定路由,如果是播放頁面,就顯示按鈕,不是,就隱藏按鈕。

axios和網易云api

axios具體的配置我都在上面講了,這里介紹一款網易云的api和使用方法。

文檔在此

介紹一下使用方法,進入git把它下下來,在命令行執行:

$ node app.js

在瀏覽器輸入地址:

localhost:3000

看到彈出的頁面就說明服務器啟動成功了。然后我們可以在文檔里查到具體請求的數據,比如banner啊,歌單啊,搜索啊,都能請求。我們看到前面寫的axios請求里的地址,都是具體請求的地址。

這里要注意的是,這個api默認的是沒有開啟跨域的,看app.js里有一段被隱藏的代碼就是跨域的相關設置,解除隱藏即可。

bug和未實現功能

目前還存在一個比較大的bug,就是在歌單點擊播放時,點擊第一次因為沒辦法獲取個去的url,無法播放,只有再點擊一次才能播放,這個bug暫時還沒有時間解決,會盡快解決。

然后目前還沒有實現的功能是播放列表,自然上一曲/下一曲按鈕也沒有用了,歌曲播放一遍也就停止了,這個功能不算難,抽空把它做出來。

參考資料

這個app參考了一些技術文章,給了我很大的啟發,附上鏈接。
用vue全家桶寫一個“以假亂真”的網易云音樂
DIY 一個自己的音樂播放器 2.0 來襲

結語

這個app前前后后,磨磨蹭蹭做了兩個月,好歹總算是做完了。學習還是得找項目來做,雖然這個項目還很簡陋,但是還是get到很多知識點,對于我的提高還是蠻大的。

這種項目不算難,寫過的人也多,所以百分之八十的問題都能百度出來,剩下的百分之二十,技術社區里提個問基本能夠解決。項目還是得自己寫一遍,寫的過程中才能發現問題,也才能想辦法找到解決辦法,事情總是會比你想象的要簡單一點。

項目不算大,但要一步步寫下來總有可能有所遺漏,這里是我的GitHub,大家可以對照著看看有沒有遺漏。如果你喜歡我的項目,也希望star或者fork一波~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107099.html

相關文章

  • Vue 實現網易云音樂 WebApp

    摘要:基于等開發一款移動端音樂,界面參考了安卓版的網易云音樂布局適配常見移動端。圖標使用阿里巴巴圖標庫,中間的唱片旋轉動畫使用了實現。搜索功能實現功能搜索歌手歌單歌曲熱門搜索數據節流上拉刷新保存搜索記錄。 基于 Vue(2.5) + vuex + vue-router + vue-axios +better-scroll + Scss + ES6 等開發一款移動端音樂 WebApp,UI ...

    Karuru 評論0 收藏0
  • Vue 寫出好看又好音樂放器 - Vue-APlayer

    摘要:好看又好用的,專為以為原型,在技術棧上進行實現。項目早在就已起步,起初是對的簡單封裝。現仍在持續維護和更新中。如果你在使用搭建自己心愛的小站,正想挑選一款好看又好用的音樂播放器,是少數不錯的選擇。 Vue-APlayer showImg(https://segmentfault.com/img/remote/1460000013797187); showImg(https://segm...

    tomato 評論0 收藏0

發表評論

0條評論

appetizerio

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<