關於音樂播放器項目詳細解析

 

 

項目碼雲地址:https://gitee.com/Snow28/MyMusic(如果覺得可以,麻煩給我鼓勵一個star)

這個是基於Vue2.0,vuex,vue-router,axios和html5的flexible box佈局與及css3的transform,animation,transition組成。

技術棧

  • vue
  • vue-router
  • vuex
  • axios
  • jsonp
  • better-scroll
  • good-storage

主要功能:

  • 歌曲播放(從搜索歷史添加到播放列表,展示最近播放)
  • 根據歌曲進度展示歌詞,提供進度條
  • 歌曲收藏
  • 個人頁面:顯示個人的最近播放和個人收藏
  • 排行榜單頁面: 幾種榜單,詳情頁顯示排行數字
  • 歌曲搜索(按人名,按歌名,刪除搜索歷史,無法搜索到歌曲頁面): 搜索框監聽內容變化顯示搜索結果,搜索結果上拉加載,點擊搜索結果添加到當前播放列表並播放該歌曲,搜索爲歌手跳轉歌手詳情頁;保存搜索歷史,顯示熱門搜索標籤
  • 熱門歌單列表頁面
  • 歌手頁面:按姓氏首字母排列,點擊側面字母欄跳轉到對應歌手區域
  • 推薦頁面:推薦歌單
  • 播放頁面: 旋轉大頭像,播放時間,進度條,切換歌曲(上一首,下一首) ,收藏,播放模式(單曲-順序-隨機),歌詞頁,播放按鈕,迷你底部播放欄(播放頁收起時顯示)

文件目錄:

項目是由vue-cli腳手架搭建的,

關於src文件中源代碼的內容:

api處理:

項目數據全是線上抓取的,在qq音樂的官網可以抓取文件的url和相應的請求參數。

在抓取數據過程中,遇到了跨域問題,ajax並不能實現跨域,於用到了jsonp技術。在common文件夾下封裝了jsonp的請求方法,

export default function jsonp(url, data, option) {
  url += (url.indexOf('?') < 0 ? '?' : '&') + param(data)
  return new Promise((resolve, reject) => {
    originJsonp(url, option, (err, data) => {
      if (!err) {
        resolve(data)
      } else {
        reject(err)
      }
    })
  })
}
export function param(data) {
  let url = ''
  for (var k in data) {
    let value = data[k] !== undefined ? data[k] : ''
    url += '&' + k + '=' + encodeURIComponent(value)
  }
  return url ? url.substring(1) : ''
}

處理了url的拼接和轉碼。

在base文件中,寫的是在很多地方相同的功能組件,例如:搜索框組件,搜索列表主鍵,滾動功能組件,歌去列表展示組件,tab導航組件。

在comon文件中,存放了靜態的字體文件,圖片文件,stylus樣式文件,還有一些封裝好功能的js組件(如:數據緩存功能,還有不能jsonp請求的接口,需要用vue中proxy做代理的,還有在多個vue組件中都會用到的方法寫在mixin.js文件中)

components文件就是我們開發主要功能目錄

router文件中定義一個index.js文件,在裏面管理路由的跳轉

store文件中主要負責vuex代碼,定義數據的state狀態,修改並相應數據狀態

main.js入口文件代碼如下所示:

在入口文件引入了vue-router路由,store的數據存儲狀態,vuex全局狀態管理,fastclick(避免移動端點擊延遲300ms的效果)以及vue-lazyload懶加載模塊。

vue-router引入頁面路由,對頁面組件進行導航,其中其他引入大多是自定義的頁面組件:

store文件中:
關於vuex全局保存各個組件共享的數據與及改變數據的邏輯,全部保存在store的index.js裏面,這是關鍵文件。包括利用數組模擬隊列進行播放歌曲的保存,搜索歷史的保存等關鍵邏輯。

App.vue組件

是整個項目的根目錄組件,在這裏掛載其他所有的組件。m-header是QQ音樂的頭部,tab組件是導航欄部分。router-view是將點擊tab單項匹配到路由組件加載到這塊內容。player就是音樂控制面板,當音樂詳情關閉,則就以小化的面板控制音樂。

vuex集中狀態管理 :

  • 搜索歷史,收藏列表,播放歷史
  • 播放狀態,播放模式,收起播放頁,當前播放索引
  • 排行榜數據,推薦歌單數據,歌手數據(進入詳情頁使用)

完成該項目的難點:

數據抓取

存儲本地數據和瀏覽器數據的業務邏輯,頁面刷新後,數據狀態不會改變

組件的複用

better-scroll 移動端插件(每次dom渲染要重新計算scroll寬度),封裝成組件。

vuex狀態管理的項目結構設計

幾種歷史記錄收藏列表存儲在localStorage

 

 

1.1 解決Vue動態路由參數變化,頁面數據不更新

問題描述:

遇到動態路由如:/page/:id
從/page/1 切換到 /page/2 發現頁面組件沒有更新

解決方式:
給<router-view :key="key">增加一個不同:key值,這樣vue就會識別這是不同的了。 

<router-view :key="key"></router-view>
  ...
  computed:{
        key(){
            return this.$route.path + Math.random();
        }
    }

1.2 vue組件裏定時器銷燬問題

問題描述:
在a頁面寫一個定時器,每秒鐘打印一次,然後跳轉到b頁面,此時可以看到,定時器依然在執行。
推薦的解決方式:
通過$once這個事件偵聽器器在定義完定時器之後的位置來清除定時器。

const timer = setInterval(() => {
    // 定時器操作
}, 1000)

// 通過$once來監聽定時器,在beforeDestroy鉤子可以被清除。
this.$once('hook:beforeDestroy', () => {            
    clearInterval(timer);                                    
})

1.3 vue實現按需加載組件的兩種方式

1.使用resolve => require(['./ComponentA'], resolve),方法如下:

const ComponentA = resolve => require(['./ComponentA'], resolve)
  1. 使用 () => import(), 具體代碼如下:
const ComponentA = () => import('./ComponentA')

1.4 組件之間,父子組件之間的通信方案

組件之間的通信方案:

  • 通過事件總線(bus),即通過發佈訂閱的方式
  • vuex
  • 父子組件:
  • 父組件通過prop向自組件傳遞數據
  • 子組件綁定自定義事件,通過this.$emit(event,params) 來調用自定義事件
  • 使用vue提供的$parent/$children & $refs方法來通信
  • provide/inject
  • 深層次組件間的通信 $attrs, $listeners

實現細節可參考:https://m.jb51.net/article/167304.htm

1.5 vue中 $event 的用法--獲取當前父元素,子元素,兄弟元素

<button @click = “fun($event)”>點擊</button>
  ...
  
  methods: {
   fun(e) {
    // e.target 是你當前點擊的元素
    // e.currentTarget 是你綁定事件的元素
    #獲得點擊元素的前一個元素
    e.currentTarget.previousElementSibling.innerHTML
    #獲得點擊元素的第一個子元素
    e.currentTarget.firstElementChild
    # 獲得點擊元素的下一個元素
    e.currentTarget.nextElementSibling
    # 獲得點擊元素中id爲string的元素
    e.currentTarget.getElementById("string")
    # 獲得點擊元素的string屬性
    e.currentTarget.getAttributeNode('string')
    # 獲得點擊元素的父級元素
    e.currentTarget.parentElement
    # 獲得點擊元素的前一個元素的第一個子元素的HTML值
    e.currentTarget.previousElementSibling.firstElementChild.innerHTML
  
    }
        },

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章