Bootstrap

微信小程序歌曲列表页实现

微信小程序组件化实现歌单效果

微信小程序的上拉加载与下拉刷新

微信小程序路由改造

以上三篇文章实现了歌单页面,并对云函数进行了路由改造,接下来完成歌曲列表页。

歌单效果:

在这里插入图片描述

页面跳转

点击歌单项,需要将歌单id传递给歌曲列表页,每个歌单项是通过自定义组件实现的,所以需要在歌单playlist组件中实现跳转和参数传递

在playlist组件的js文件中添加goToMusiclist方法,如下:

  methods: {

    goToMusiclist() {
      wx.navigateTo({
        url: `../../pages/musiclist/musiclist?playlistId=${this.properties.playlist.id}`,
      })
    },
...

}

在playlist组件的wxml文件中添加点击事件
在这里插入图片描述

新建musiclist页面,在musiclist.js的onLoad方法打印接收到的数据

  onLoad: function (options) {
    console.log(options)
  },

点击任一歌单,进入musiclist页面,打印以下信息,说明页面跳转成功,并成功接收到了playlistId参数。
在这里插入图片描述


实现流程如下入所示:

在这里插入图片描述

添加云函数路由

在music云函数中添加musiclist路由

 // 云函数入口文件
const cloud = require('wx-server-sdk')
const TcbRouter = require('tcb-router')
const rp = require('request-promise')
const BASE_URL = 'http://xx.xx.xx'

cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {

  const app = new TcbRouter({
    event
  })

  app.router('playlist', async (ctx, next) => {
    ctx.body = await cloud.database().collection('playlist')
      .skip(event.start)
      .limit(event.count)
      .orderBy('createTime', 'desc')
      .get()
      .then((res) => {
        return res
      })
  })

  //这里直接将歌单详情接口中请求的数据返回给调用者
  app.router('musiclist', async (ctx, next) => {
    ctx.body = await rp(BASE_URL + '/playlist/detail?id=' + parseInt(event.playlistId))
      .then((res) => {
        console.log(res)
        return JSON.parse(res)
      })
  })

  return app.serve()
}
 

musiclist自定义组件

新建musiclist自定义组件

musiclist.wxml :

<block wx:for="{{musiclist}}" wx:key="id">
  <view class="musiclist-container {{item.id === playingId ? 'playing': ''}}" 
  bind:tap="onSelect" data-musicid="{{item.id}}" data-index="{{index}}">
    <view class="musiclist-index">{{index+1}}</view>
    <view class="musiclist-info">
      <view class="musiclist-name">
        {{item.name}}
        <text class="musiclist-alia">{{item.alia.length==0?"":item.alia[0]}}</text>
      </view>
      <view class="musiclist-singer">{{item.ar[0].name}} - {{item.al.name}}</view>
    </view>
  </view>
</block>

musiclist.js :

// components/musiclist/musiclist.js
const app = getApp()
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    musiclist: Array
  },

  /**
   * 组件的初始数据
   */
  data: {
    playingId: -1
  },
  pageLifetimes: {
    show() {
      this.setData({
        playingId: parseInt(app.getPlayMusicId())
      })
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    onSelect(event) {
      console.log('被选中了')
      // 事件源 事件处理函数 事件对象 事件类型
      // console.log(event.currentTarget.dataset.musicid)
      const ds = event.currentTarget.dataset
      const musicid = ds.musicid
      this.setData({
        playingId: musicid
      })
      wx.navigateTo({
        url: `../../pages/player/player?musicId=${musicid}&index=${ds.index}`,
      })
    }
  }
})

musiclist.wxss :

.musiclist-container {
  display: flex;
  padding: 14rpx 20rpx;
  align-items: center; /* 垂直居中 */
}

.musiclist-index {
  color: #888;
  font-size: 34rpx;
  width: 80rpx;
}

.musiclist-info {
  flex-grow: 1;
  width: 0;
}

.musiclist-name {
  font-size: 34rpx;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-bottom: 10rpx;
}

.musiclist-alia {
  color: #888;
}

.musiclist-singer {
  font-size: 24rpx;
  color: #888;
}

.playing view, .playing text {
  color: #d43c33;
}

歌曲列表页面实现

新建musiclist歌曲列表页面

在musiclist.json 中引入musiclist自定义组件

{
  "usingComponents": {
    "x-musiclist": "/components/musiclist/musiclist"
  }
}

musiclist.wxml :

<view class='detail-container' style='background: url({{listInfo.coverImgUrl}}) no-repeat  top/cover'></view>
<view class='detail-mask'></view>
<view class='detail-info'>
  <image src="{{listInfo.coverImgUrl}}" class='detail-img'></image>
  <view class='detail'>
    <view class='detail-nm'>{{listInfo.name}}</view>
  </view>
</view>

<x-musiclist musiclist="{{musiclist}}" />

musiclist.wxss :

.detail-container {
  height: 320rpx;
  filter: blur(40rpx);
  opacity: 0.4;
}

.detail-mask {
  position: absolute;
  width: 100%;
  height: 320rpx;
  background-color: #333;
  top: 0;
  left: 0;
  z-index: -1;
}

.detail-img {
  width: 280rpx;
  height: 280rpx;
  margin-right: 24rpx;
  border-radius: 6rpx;
}

.detail-info {
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 320rpx;
  padding: 20rpx;
  box-sizing: border-box;
  align-items: center;
}

.detail {
  flex-grow: 1;
  line-height: 60rpx;
  width: 0;
}

.detail view {
  color: #fff;
  font-size: 24rpx;
}

.detail .detail-nm {
  font-size: 36rpx;
  font-weight: 400;
}

musiclist.js :

// pages/musiclist/musiclist.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    musiclist: [],
    listInfo: {},
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    console.log(options)
    wx.showLoading({
      title: '加载中',
    })
    //调用music云函数的musiclist路由,获取歌曲列表数据
    wx.cloud.callFunction({
      name: 'music',
      data: {
        playlistId: options.playlistId,
        $url: 'musiclist'
      }
    }).then((res) => {
      console.log(res)
      const pl = res.result.playlist
      this.setData({
      	//歌单详情中的歌曲列表数据
        musiclist: pl.tracks,
        //歌单封面和歌单名
        listInfo: {
          coverImgUrl: pl.coverImgUrl,
          name: pl.name,
        }
      })
      wx.hideLoading()
    })
  },
})

实现效果如下:
在这里插入图片描述

;