当前位置:网站首页>微信小程序实现音乐播放器(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();
})
}
})
相关链接
边栏推荐
- Completion report of communication software development and Application
- 赶紧进来!!!用c语言基础知识几十行代码写一个猜数字小游戏
- Bracket nesting problem (recommended Collection)
- 6-40v input fixed 5V 3.3V output 1.1a current 23-5 package
- JS Base64 encoding and decoding
- [programmers must] Tanabata confession strategy: "the moon meets the cloud, the flowers meet the wind, and the night sky is beautiful at night". (with source code Collection)
- [MySQL project practical optimization] complex trigger case sharing
- MySQL索引失效场景以及解决方案
- bond网络模式配置
- Sersync/lsync real-time synchronization
猜你喜欢

用GaussDB(for Redis)存画像,推荐业务轻松降本60%

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

Matlab paper illustration drawing template issue 39 - stairs

Portable power fast charging scheme 30W automatic pressure rise and fall PD fast charging

Apply for SSL certificate, configure SSL certificate for domain name, and deploy server; Download and installation of SSL certificate

What are you interviewing for in a big factory? It's worth watching (I)

zk-SNARK:关于私钥、环签名、ZKKSP

Configuration and use of virtualservice, gateway and destinationrule of istio III

C语言函数(2)

基于JSP实现网上商城系统
随机推荐
9-20v input peak charging current 3A dual lithium switch type charging chip sc7102
Sentinel vs Hystrix 到底怎么选?
DDD landing is called an advanced
C语言预处理指令以及Makefile脚本讲解
Usage of tf.variable() function in tensorflow
Performance comparison of ext4, NTFS, XFS, Btrfs, ZFS, f2fs and ReiserFS
深度学习之SuperViT
Six years of automated testing from scratch, I don't regret turning development to testing
Three solutions: when clicking the user to exit the login, press the back button of the browser, and you can still see the previous login page.
Tf.constant usage
Portable power fast charging scheme 30W automatic pressure rise and fall PD fast charging
[mathematical modeling - Summary of planning model] | matlab solution
The convolution kernel is expanded to 51x51, and the new CNN architecture slak counterattacks the transformer
Realization of online shopping mall system based on JSP
ELS message loop
Leetcode-169. most elements
HCIP第十四天
使用VRRP技术实现网关设备冗余,附详细配置实验
MPLS基础实验配置
Dtcloud the next day