zoukankan      html  css  js  c++  java
  • 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 `icon icon${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,
        };
      },

  • 相关阅读:
    APP与智能手表是如何通信的【本文摘抄自深圳尚锐科技】
    flash添加超链接的办法
    NPOI使用手册
    如何在 SQL Server 实例之间传输登录和密码
    CentOS 7 上部署Mono 4 和Jexus 5.6
    django models 中choices之用法举例
    django中的objects.get和objects.filter方法的区别
    Django中的Model.objects.create() 和 Model() 的区别?
    python爬虫练手项目快递单号查询
    根据现有的数据库自动生成Django model
  • 原文地址:https://www.cnblogs.com/Small-Windmill/p/14942535.html
Copyright © 2011-2022 走看看