当前位置:网站首页>微信小程序实现音乐播放器(4)(使用pubsubjs实现页面间通信)
微信小程序实现音乐播放器(4)(使用pubsubjs实现页面间通信)
2022-07-26 03:43:00 【richest_qi】
文章目录
前情提要
消息订阅与发布的基本使用
npm install --save pubsub-js,安装第三方库pubsub-js。import PubSub from "pubsub-js",引入第三方库pubsub。- 订阅消息:
id = PubSub.subscribe(消息名,callback),且callback的第一个形参默认是消息名,后面则是开发者自己传入的参数。 - 发布消息:
PubSub.publish(消息名,开发者的参数)。 - 取消订阅:
PubSub.unsubscribe(id)。
小程序项目
- 初始化项目。小程序根目录下执行
npm init -y,自动生成package.json。 - 下载安装依赖。
npm install --save pubsub-js。 - 页面pages/music/music.js中引入依赖。
import PusSub from "pubsub-js"。
遇到如下报错:页面【pages/music/music]错误:
Error: module ‘pages/music/pubsub-js.js’ is not defined, require args is ‘pubsub-js’。 - 微信开发者工具中,工具 > 构建npm,会自动把
node_modules中的第三方依赖转换成小程序可以使用的包,并保存在同级文件夹miniprogram_npm中。
- 消息订阅:
消息ID=PubSub.subscribe(消息名,(msgName,接收的数据) => {})
取消订阅:PubSub.unsubscribe(消息ID)
消息发布:PubSub.publish(消息名,发送的数据)
小程序代码涉及的主要文件有:
- app.json
- app.wxss
- app.js
- pages/index/index.json
- pages/index/index.wxml
- pages/index/index.wxss
- pages/index/index.js
- pages/music/music.json
- pages/music/music.wxml
- pages/music/music.wxss
- pages/music/music.js
app.json
{
"pages": [
"pages/index/index",
"pages/music/music"
],
"window": {
"navigationBarBackgroundColor": "#624d2e",
"navigationBarTitleText": "首页",
"navigationBarTextStyle": "white"
},
"requiredBackgroundModes": [
"audio"
],
"style": "v2",
"sitemapLocation": "sitemap.json"
}
app.wxss
page{
height: 100%;
}
app.js
App({
globalData:{
isPlayGlobal:false, //当前是否有歌曲在播放
musicIdGlobal:'' //当前正在播放的歌曲是哪首
}
})
pages/index/index.json
{
"usingComponents": {
},
"navigationBarTitleText": "播放列表"
}
pages/index/index.wxml
<view class="index-container">
<view class="header">
<image src="/static/images/icon-play-square.png"></image>
<text>播放全部</text>
<text>{
{musicList.length}}</text>
</view>
<scroll-view class="music-list" enable-flex scroll-y >
<view class="music-item" wx:for="{
{musicList}}" wx:key="id" bindtap="handleTap" data-musicindex="{
{index}}" data-musicitem="{
{item}}">
<view class="music-index">{
{index+1}}</view>
<image class="music-image" src="{
{item.picUrl}}"></image>
<view class="music-info">
<view class="musci-name">{
{item.name}}</view>
<view class="music-author">{
{item.author}}</view>
</view>
<image class="btn-more" src="/static/images/icon-more.png"></image>
</view>
</scroll-view>
</view>
pages/index/index.wxss
.index-container{
padding: 20rpx;
background:#624d2e
}
.header{
display: flex;
align-items: center;
}
.header image{
width: 28rpx;
height: 28rpx;
margin-right: 20rpx;
}
.header text{
color: #fff;
height: 28rpx;
line-height: 28rpx;
margin-right: 20rpx;
font-size: 28rpx;
}
.music-list{
margin-top: 20rpx;
color: #fff;
height: calc(100vh - 88rpx);
}
.music-item{
display: flex;
align-items: center;
height: 100rpx;
margin: 20rpx 0;
position: relative;
}
.music-item .music-index{
width: 50rpx;
font-size: 28rpx;
color: #aaa;
}
.music-item .music-image{
width: 80rpx;
height: 80rpx;
border-radius: 6rpx;
margin-right: 20rpx;
}
.music-item .music-info{
display: flex;
flex-direction: column;
}
.music-item .music-info .music-author{
font-size: 24rpx;
color: #aaa;
margin-top: 10rpx;
}
.music-item .btn-more{
width: 36rpx;
height: 36rpx;
position: absolute;
right: 0;
}
pages/index/index.js
import PubSub from "pubsub-js";
const host = "http://localhost:3000";
Page({
data:{
musicList:[], //歌曲列表
musicindex:0 //进入某首歌曲后,记录该歌曲在列表中的索引
},
onLoad(){
this.getDataFromServer();
//接收消息,接收来自页面pages/music/music的消息,根据“上一首”or“下一首”,确定当前应该显示哪首歌曲
PubSub.subscribe("switchsong",(msgName,type) => {
// console.log(msgName,type);
let {
musicindex,musicList} = this.data;
if(type === "prev"){
if(musicindex===0) {
musicindex = musicList.length-1;
}else{
musicindex--;
}
}else if(type === "next"){
if(musicindex === musicList.length-1){
musicindex = 0;
}else{
musicindex++;
}
}
this.setData({
musicindex});
const music = musicList[musicindex];
//发送消息,告诉页面pages/music/music,告诉它切换完成后的歌曲的详细消息。
PubSub.publish("refreshmusic",music);
})
},
getDataFromServer(){
const result = [
{
id:"001",name:"滂沱大雨里","author":"李若溪","picUrl":host+"/images/滂沱大雨里.jpg","url":host+"/audios/滂沱大雨里.mp3",duration:161000},
{
id:"002",name:"Last Dance","author":"伍佰","picUrl":host+"/images/Last Dance.jpg","url":host+"/audios/Last Dance.mp3",duration:271000},
{
id:"003",name:"国王与乞丐","author":"华晨宇","picUrl":host+"/images/国王与乞丐.jpg","url":host+"/audios/国王与乞丐.mp3",duration:178000},
{
id:"004",name:"奇洛李维斯回信","author":"薛凯琪","picUrl":host+"/images/奇洛李维斯回信.jpg","url":host+"/audios/奇洛李维斯回信.mp3",duration:243000},
{
id:"005",name:"红日","author":"李克勤","picUrl":host+"/images/红日.jpg","url":host+"/audios/红日.mp3",duration:291000},
{
id:"006",name:"快乐崇拜","author":"潘玮柏 张韶涵","picUrl":host+"/images/快乐崇拜.jpg","url":host+"/audios/快乐崇拜.mp3",duration:329000},
{
id:"007",name:"门没锁","author":"黄品冠","picUrl":host+"/images/门没锁.jpg","url":host+"/audios/门没锁.mp3",duration:233000},
{
id:"008",name:"就是爱你","author":"陶喆","picUrl":host+"/images/就是爱你.jpg","url":host+"/audios/就是爱你.mp3",duration:340000},
{
id:"009",name:"快乐的小青蛙","author":"刘士鸣","picUrl":host+"/images/快乐的小青蛙.jpg","url":host+"/audios/快乐的小青蛙.mp3",duration:130000},
{
id:"0010",name:"友情岁月","author":"陈小春 郑伊健 谢天华 林晓峰 钱嘉乐","picUrl":host+"/images/友情岁月.jpg","url":host+"/audios/友情岁月.mp3",duration:209000},
{
id:"0011",name:"温柔","author":"五月天","picUrl":host+"/images/温柔.jpg","url":host+"/audios/温柔.mp3",duration:269000}
];
this.setData({
musicList:result});
},
handleTap(event){
const {
musicitem,musicindex} = event.currentTarget.dataset;
this.setData({
musicindex})
wx.navigateTo({
url: '/pages/music/music?musicitem='+JSON.stringify(musicitem),
})
}
})
pages/music/music.json
{
"usingComponents": {
},
"navigationBarBackgroundColor": "#2f434e",
"navigationBarTitleText": "音乐详情"
}
pages/music/music.wxml
<view class="music-container">
<view class="music-name">{
{music.name}}</view>
<view class="music-author">{
{music.author}}</view>
<image class="arm {
{isPlay&&'arm-reset'}}" src="/static/images/arm.png"></image>
<view class="disc-container {
{isPlay&&'disc-animate'}}">
<image class="disc" src="/static/images/disc.png"></image>
<image class="music-image" src="{
{music.picUrl}}"></image>
</view>
<view class="player">
<view class="btns">
<image class="loop-btn" src="/static/images/loop.png"></image>
<image class="prev-btn" src="/static/images/prev.png" id="prev" bindtap="handleSwitch"></image>
<image class="play-btn" src="{
{isPlay?'/static/images/stop.png':'/static/images/play.png'}}" bindtap="handlePlay"></image>
<image class="next-btn" src="/static/images/next.png" id="next" bindtap="handleSwitch"></image>
<image class="list-btn" src="/static/images/list.png"></image>
</view>
</view>
</view>
pages/music/music.wxss
.music-container{
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background: #2f434e;
position: relative;
}
.music-container .music-name{
margin: 10rpx 0;
color: #fff;
font-size: 36rpx;
}
.music-container .music-author{
color: #bbb;
font-size: 28rpx;
margin: 6rpx 0;
}
.music-container .arm{
width:204rpx;
height: 358rpx;
position: relative;
left: 72rpx;
z-index: 99;
transform: rotate(-15deg);
transform-origin: 30rpx 30rpx;
transition: transform .7s linear;
}
.disc-container{
position: relative;
top: -128rpx;
width: 490rpx;
height: 490rpx;
}
.disc-container .disc{
width: 100%;
height: 100%;
}
.disc-container .music-image{
width: 270rpx;
height: 270rpx;
border-radius: 100%;
position: absolute;
left: 0;right: 0;top: 0;bottom: 0;
margin: auto;
}
.music-container .arm-reset{
transform: rotate(0deg);
}
.disc-animate{
animation: rotate 2.5s 1s linear infinite;
}
@keyframes rotate{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
.player{
width: 100%;
position: absolute;
bottom: 60rpx;
}
.btns{
display: flex;
align-items: center;
justify-content: space-evenly;
}
.btns image{
width: 36rpx;
height: 36rpx;
}
.btns .play-btn,.btns .stop-btn{
width: 90rpx;
height: 90rpx;
}
pages/music/music.js
import PubSub from "pubsub-js";
const appInstance = getApp();
Page({
data:{
isPlay:false,
music:{
}
},
onLoad(options){
const music = JSON.parse(options.musicitem);
this.setData({
music})
const {
isPlayGlobal,musicIdGlobal} = appInstance.globalData;
const {
id} = this.data.music;
if(isPlayGlobal && musicIdGlobal === id) {
this.setData({
isPlay:true});
}
this.bam = wx.getBackgroundAudioManager();
this.bam.onPlay(() => {
this.setData({
isPlay:true})
appInstance.globalData.isPlayGlobal = true;
appInstance.globalData.musicIdGlobal = this.data.music.id;
})
this.bam.onPause(() => {
this.setData({
isPlay:false})
appInstance.globalData.isPlayGlobal = false;
})
this.bam.onStop(() => {
this.setData({
isPlay:false})
appInstance.globalData.isPlayGlobal = false;
})
this.bam.onEnded(() => {
this.setData({
isPlay:false});
appInstance.globalData.isPlayGlobal = false;
})
},
handlePlay(){
const isPlay = !this.data.isPlay;
this.setData({
isPlay});
this.musicControl();
},
musicControl(){
const {
isPlay} = this.data;
if(isPlay){
this.bam.src = this.data.music.url;
this.bam.title = this.data.music.name;
}else{
this.bam.pause();
}
},
handleSwitch(event){
const type = event.target.id;
//发送消息,告诉pages/index/index:切上一首还是下一首。prev代表切上一首,next代表切下一首。
PubSub.publish("switchsong",type);
//接收消息,接收来自pages/index/index的消息,显示切换后的歌曲详情
const eventId = PubSub.subscribe("refreshmusic",(msgName,music) => {
// console.log(msgName,music);
PubSub.unsubscribe(eventId);
this.setData({
music})
this.musicControl();
})
}
})
相关链接
边栏推荐
- Usage of tf.variable() function in tensorflow
- Apply for SSL certificate, configure SSL certificate for domain name, and deploy server; Download and installation of SSL certificate
- Three ways of redis cluster
- What is the problem of the time series database that has been developed for 5 years?
- IDEA2020.3.1不能打开(双击不能打开),但可以通过idea.bat打开。
- Booking.com binke Shanghai noodles
- 大厂面试都面试些啥,看了不亏(一)
- [mathematical modeling - Summary of planning model] | matlab solution
- NFT is beautiful because it is meaningless
- Easyexcel sets row hiding to solve the problem of sethidden (true) invalidation
猜你喜欢

Where can Lora and nb-iot be used

The B2B2C multi merchant system has rich functions and is very easy to open

Multi merchant mall system function disassembly lecture 15 - platform side member label

Hurry in!!! Write a number guessing game with dozens of lines of code based on the basic knowledge of C language

【 Kotlin 中的类和对象实例】

Performance comparison of ext4, NTFS, XFS, Btrfs, ZFS, f2fs and ReiserFS

Data elements

Easyexcel sets row hiding to solve the problem of sethidden (true) invalidation

6年从零开始的自动化测试之路,开发转测试我不后悔...

Course selection information management system based on SSM
随机推荐
文件上传报错:Current request is not a multipart request
2020 AF-RCNN: An anchor-free convolutional neural network for multi-categoriesagricultural pest det
Zkevm: summary of zkevm and L1 by Mina's CEO
9-20v input peak charging current 3A dual lithium switch type charging chip sc7102
Configuration and use of virtualservice, gateway and destinationrule of istio III
Can UDP and TCP use the same port?
Div setting height does not take effect
FPS game reverse - box Perspective (matrix)
安装VMware报错failed to install the hcmon driver
LoRa和NB-IOT可用用在哪些地方
Moco V2: further upgrade of Moco series
Performance comparison of ext4, NTFS, XFS, Btrfs, ZFS, f2fs and ReiserFS
Hcip day 14
The B2B2C multi merchant system has rich functions and is very easy to open
div设置高度不生效
Oracle 11g "password delayed verification" feature
触觉智能分享-RK3568在景区导览机器人中的应用
开源许可证的传染性问题浅析
tf.truncated_ Normal() usage
ASEMI整流桥GBU1510参数,GBU1510规格,GBU1510封装