1. 程式人生 > 其它 >VUE移動端音樂APP學習【十九】:排行榜詳情頁開發

VUE移動端音樂APP學習【十九】:排行榜詳情頁開發

排行榜詳情頁和之前的歌手詳情頁、歌單詳情頁佈局類似,除了資料不同之外還多了排行榜排名的樣式,整體上還是可以複用之前的元件。

初始化程式碼:

<template>
  <transition name="slide">
    <music-list></music-list>
  </transition>
</template>

<script>
import musicList from '../music-list/music-list.vue';

export default {
  name: 'top-list
', components: { musicList }, }; </script> <style lang="scss" scoped> .slide-enter-active, .slide-leave-active { transition: all 0.3s ease; } .slide-enter, .slide-leave-to { transform: translate3d(100%, 0, 0); } </style>
View Code

因為這是個子路由元件,需要在router.js裡設定該路由。

import TopList from '../components/top-list/top-list';

//定義在rank的children下 { path: '/rank', name: 'Rank', component: Rank, children: [{ path: ':id', component: TopList, }], },

rank.vue中實現點選跳轉到toplist事件

<template>
  <div class="rank" ref="rank">
    <scroll :data="topList" class="toplist" ref="toplist">
<ul> <li class="item" v-for="(item,index) in topList" :key="index" @click="selectItem(item)"> ...... </scroll> <router-view></router-view> </div> </template>
 selectItem(item) {
      // 呼叫router的api
      this.$router.push({
        path: `/rank/${item.id}`,
      });
    },

toplist.vue中通過獲取路由引數(this.$route.params)獲取到排行榜歌單詳情列表

import { getSongList } from '../../api/recommend';
import { ERR_OK } from '../../api/config';

created() {
    this._getTopList();
  },

data() {
    return {
      topList: [],
    };
  },
  methods: {
    _getTopList() {
      getSongList(this.$route.params.id).then((res) => {
        if (res.code === ERR_OK) {
          this.topList = res.playlist;
          console.log(this.topList);
        }
      });
    },
  },

computed中設定標題和圖片,把這2個數據傳到music-list裡面

<music-list :title="title" :bgImage="bgImage"></music-list>


computed: {
    title() {
      return this.topList.name;
    },
    bgImage() {
      return this.topList.coverImgUrl;
    },
  },

接下來是處理排行榜歌單列表,需要使用createSong以及_normalizeSongs將資料例項化傳到music-list中

<music-list :title="title" :bgImage="bgImage" :songs="songs"></music-list>
import { createSong } from '../../common/js/song';

data() {
    return {
      topList: [],
      songs: [],
    };
  },

 methods: {
    _getTopList() {
      getSongList(this.$route.params.id).then((res) => {
        if (res.code === ERR_OK) {
          this.topList = res.playlist;
          this.songs = this._normalizeSongs(this.topList.tracks);
        }
      });
    },
    _normalizeSongs(list) {
      let ret = [];
      list.forEach((item) => {
        if (item.id && item.al.id) {
          ret.push(createSong(item));
        }
      });
      return ret;
    },
  },

封面可能看起來很醜,可以將其替換為第一首歌的圖片

bgImage() {
      if (this.songs.length) {
        return this.songs[0].image;
      }
      return '';
    },

最後是擴充套件榜單樣式

  • 在song-list中新增幾張榜單圖片並新增CSS樣式
.rank {
        flex: 0 0 25px;
        width: 25px;
        margin-right: 30px;
        text-align: center;

        .icon {
          display: inline-block;
          width: 25px;
          height: 24px;
          background-size: 25px 24px;

          &.icon0 {
            @include bg-image('first');
          }

          &.icon1 {
            @include bg-image('second');
          }

          &.icon2 {
            @include bg-image('third');
          }
        }

        .text {
          color: $color-theme;
          font-size: $font-size-large;
        }
      }
  • props需要擴充套件一個欄位rank,型別為boolean值
 props: {
    songs: {
      type: Array,
      // eslint-disable-next-line vue/require-valid-default-prop
      default: [],
    },
    rank: {
      type: Boolean,
      // 預設它是沒有排行的樣式
      default: false,
    },
  },
  • 擴充套件dom:除了歌曲的名字和描述之外,擴充套件一個rank樣式通過v-show決定是否顯示以及設定它顯示的樣式和文字
 <div class="song-list">
    <ul>
      <li @click="selectItem(song,index)" v-for="(song,index) in songs" class="item" :key="song.id">
        <div class="rank" v-show="rank">
          <span :class="getRankCls(index)">{{getRankText(index)}}</span>
        </div>
        <div class="content">
          <h2 class="name">{{song.name}}</h2>
          <p class="desc">{{getDesc(song)}}</p>
        </div>
      </li>
    </ul>
  </div>
//定義2個methods方法
 getRankCls(index) {
      // 前3名就返回圖片的樣式
      if (index <= 2) {
        return `iconicon${index}`;
      } else {
        return 'text';
      }
    },
    // eslint-disable-next-line consistent-return
    getRankText(index) {
      if (index > 2) {
        return index + 1;
      }
    },
  • 在music-list擴充套件這個rank欄位,然後把這個rank傳到songlist作為它的屬性
<div class="song-list-wrapper">
        <song-list :rank="rank" @select="selectItem" :songs="songs"></song-list>
</div>



rank: {
      type: Boolean,
      default: false,
    },
  • 在呼叫music-list傳遞rank為true讓它顯示排行榜的樣式
  <transition name="slide">
    <music-list :rank="true" :title="title" :bgImage="bgImage" :songs="songs"></music-list>
  </transition>


data() {
    return {
      topList: [],
      songs: [],
      rank: true,
    };
  },