VUE練手項目實現音樂播放器(二)-------排行榜組件


今天,我們來實現播放器首頁的 排行榜頁面 的開發,也就是 src\components\Rank.vue ,效果截圖:

 

排行榜頁面

 

主要分析要點:

1、Vuex模塊化

2、CSS屏幕自適應——@media screen

3、overflow CSS處理文本溢出

4、absolute 絕對定位

 

頁面的圖片、排行榜名稱、歌曲等信息,來自QQ音樂的數據接口,我們用 vue-resource 插件的 Vue.http.jsonp() 獲取接口數據,這個頁面的難點是CSS布局,主要用到 display:flex 彈性布局,中間還有不少細節,我們一起來分析。

 

首先,獲取數據,用到的是Vuex,與其在每個需要獲取接口數據的組件里調用接口,還不如將它們統一管理起來,寫成一個公共的函數,通過 Vuex 的 Actions 的 this.$store.dispatch('  ') 獲取即可。

 

我們來看下具體實現,首先在 src\config 下,新建 api.js ,用於 export 接口地址、參數等信息,方便下一步直接 import 調用,代碼如下:

export default {
    rank_list: {
        url: 'https://c.y.qq.com/v8/fcg-bin/fcg_myqq_toplist.fcg',
        params: () => {
            return {
                format: 'jsonp',
                g_tk: 5381,
                uin: 0,
                inCharset: 'utf-8',
                outCharset: 'utf-8',
                notice: 0,
                platform: 'h5',
                needNewCode: 1,
                _: new Date().getTime()
            }
        },
        jsonp: 'jsonpCallback'
    }
}

 

 

然后在 src\store 下新建 ApiService.js :

import Vue from 'vue'

import API from '../config/api'

function apiFactory(api) {                     //統一接口函數
  return (id = null) => Vue.http.jsonp(
    api.url,
    {
      params: api.params(id),
      jsonp: api.jsonp
    }
  )
}

export default {
  actions: {
     getRankList({}){                         //'{}'也可以省略,查看Vuex官網教程,若需要用到store和commit就寫成'{state,commit}'
      return apiFactory(API.rank_list)()      //最后的'()'是因為rank_list對象內有函數,向函數傳空參
    }
 }
}

 

 接着,在 src\store 中新建 index.js :

import Vue from 'vue'
import Vuex from 'vuex'

import ApiService from './ApiService'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    ApiService,
  }
})

 

 查看Vuex官網教程,由於我們后期用到的集中狀態較多,我們將store分成模塊,以免store對象很臃腫。

 

OK,到這里我們的后端數據獲取工作就可以啦。。

 

下面我們來編寫前端組件,我們將其命名為Rank.vue

 

先來一個 created生命周期鈎子,通過 this.$store.dispatch 獲取后端的數據:

created: function () {
  this.$store.dispatch('getRankList').then((response) => {     //調用 ApiService.js 中 Actions:getRankList
    this.topList = response.data.data.topList
  })
}

 

 

可以先將 this.topList 通過 alert() 打印出來,查看返回數據的結構,再通過 v-for 將其呈現出來,具體的代碼實現參考項目源碼,這里針對其中的 CSS 幾個知識點着重講一下。

 

1.設置屏幕自適應。

 

只需要在App.vue中即可:

@media screen and (min-width: 68vh) {
  body {
    width: 68vh;          //若屏幕寬度大於 68vh,取68vh
    margin: 0 auto;
  }
}

 

2.元素定位

                         

<div class="rank-media">
  <img class="rankpic" v-lazy="rankItem.picUrl">
  <div class="listen-count">
    {{Math.round(rankItem.listenCount/1000) / 10 + '' }} 
  </div>
</div>

 

該段代碼呈現出的是上面左圖的效果,而我們想實現右圖的效果,讓數字跑到圖片的左下角。

 

細想 display: flex 實現不了我們想要的結果,但是 position: absolute 可以實現,設置為絕對定位的元素框從文檔流完全刪除,元素原先在正常文檔流中所占的空間會關閉,就好像該元素原來不存在一樣。然后,該元素會相對於其包含塊定位,若父元素為非static(默認)定位,則相對父元素,否則相對於根元素即html元素來定位。

 

此處, .listen-count 的父元素為 .rank-media ,給前者添加 position: absolute 的同時,必須給后者 添加 position: relative :

.rank-media {
  width: 100px;
  height: 100px;
  position: relative;   //若去掉該行,.listen-count會相對body定位,達不到我們的目的
}

.listen-count {
  position: absolute;  
  font-size: 12px;
  color:white;
  bottom: 3px;
  left: 5px;
}

 

3. 文本溢出處理

 

 

我們看到,由於 第一個歌曲的 歌名過長,導致內容超出了預想的范圍,不着急,給該元素加上如下 CSS 屬性:

white-space: nowrap   //設置文本內容不換行

 

 

可是設置后,又發現 歌手名稱超出了界線,顯得頁面不美觀,只需給元素加如下 CSS 屬性:

overflow: hidden;
text-overflow: ellipsis;   //溢出部分設置為 '...'

 

最終得到如下效果:

 

這樣即使文本溢出,也不會影響頁面的美觀了。

 

下一節我們分析重點頁面之一,src\components\RankPage.vue界面,即用戶點擊自己感興趣的排行榜之后,跳轉的頁面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM