if vue 跳出_牛逼爆了,Vue高仿网易云音乐

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

Vue高仿网易云音乐,基本实现网易云所有音乐相关功能,仅用于学习,下面有详细教程。

gitee开源地址:

https://gitee.com/fudaosheng/vue-fds_music

60ed4a2043c6b7bed0de8374343df3c0.png

03cf2d24bac2419885dc958b8d719db3.png

小符音乐-高仿网易云音乐

前言

肝代码不易,本项目还是比较能拿的出手的,若是在网上发表请标明出处,另外跪求Star。本项目仅用于学习。

Github地址:https://github.com/daoshengfu/vue-fds_music

特别感谢

@北京-张嘉利 给出的解决“点击相似歌手,切换到对应歌手详情页,但是歌手基础信息不变的问题”,解决方法在评论里。

项目简介

本项目后端接口是Github大神Binaryify的开源项目(项目地址:https://github.com/Binaryify/NeteaseCloudMusicApi),接口文档直接在百度搜索“网易云音乐API”作者是Binaryify。

本项目前端均是本人独立自主开发,所用技术栈:Vue全家桶+better-scroll+axios。

项目演示:(b站)https://www.bilibili.com/video/BV1ui4y137Xr/随手点个赞吧 caaba44d945bade501a68c98a8c28767.png

下面也有项目效果图

项目准备:

后端API官方文档:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi

API安装步骤:

  1. git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git

(不会使用git的小伙伴可以直接去仓库下载接口哦,接口仓库地址:https://github.com/Binaryify/NeteaseCloudMusicApi)

  1. npm install

3.cd api文件夹

4.node app.js

93cf845ba1e7010a18ef509f4a18e3f4.png

以上是运行成功的效果

项目知识点介绍:Mixin

085e56452dec0f2578772e6bae941b22.png

了解详细Mixin请去vue官网。

项目优点

个人觉得本项目最大的优点在于如何触发音乐播放器。一般触发音乐播放器有三种方法,emit、vuex、" role="presentation" style=" display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">emit、vuex、emit、vuex、bus。

1.$emit:缺点:音乐播放器和要播放音乐所在组件必须存在父子关系,而明显在一个音乐app中这是不现实的。

2.vuex:利用vuex的话可以先将要播放的音乐放在vuex中(假设放在state的musiclist中),然后在音乐播放器组件生命周期函数中监听musiclist的状态,当音乐列表不为空时播放音乐.

缺点:(1)会存在musiclist不为空但是监听到的是空的现象,个人感觉是页面渲染先后问题。(2)修改musiclist都要通过mutations比较麻烦.

3.bus,本项目采用的就是" role="presentation" style=" display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">bus,本项目采用的就是bus,本项目采用的就是bus。使用$bus这样不论音乐播放器和要播放的音乐所在组件是何种关系,都可以监听到要播放的音乐。

本项目核心--如何播放音乐 :

import { _getMusicUrl, _getLyric } from "network/detail"
import { playList } from "components/content/playmusic/playList";
export const indexMixin = {
    methods: {
        PlayMusic(index = 0) {
            let path = this.$route.path;
            let musiclist;
            if (this.musiclist.length >= 200) {
                musiclist = this.musiclist.slice(0, 199);
            }
            else musiclist = this.musiclist;
            let url = null,
                lyric = null,
                currentLength = 0;
            let playlist = [];
            for (let i = 0, length = musiclist.length; i < length; i++) {
                let getUrl = _getMusicUrl(musiclist[i].id).then(res => {
                    url = res.data.data[0].url;
                    return url;
                });
                let getLyric = _getLyric(musiclist[i].id).then(res => {
                    lyric = res.data.tlyric.lyric;
                    return lyric;
                });
                Promise.all([getUrl, getLyric])
                    .then(results => {
                        let song = new playList(i, musiclist[i], results[0], results[1]);
                        playlist.push(song);
                        currentLength++;
                        /**每次完成两个网络请求都判断是否满足要求,满足才发送事件 */

                        if (i == musiclist.length - 1) {

                            this.$bus.$emit("playMusic", playlist, index, path);
                        }
                    })
                    .catch(err => {
                        this.$Message.warning('数据加载中,请稍等');
                    });
            }
        },
    }
}

之所以将其放在mixin中,是因为这样我在任何一个组件中都能使用这个方法,降低了代码的重复性,也体现了模块化的编程思想。

在音乐播放器组件中接收时:

mounted() {
 /**list是音乐列表,index是要播放的音乐在列表中的位置,path是当前播放音乐的路由路径 */
    this.$bus.$on("playMusic", (list, index, path) => {
      this.music = [];
      this.path = path;
      this.music = list;
      // this.music = list.filter(item => {
      // return item.src !== "";
      // });
      /**对数组进行排序 */
      this.music = this.music.sort((a, b) => {
        return a.index - b.index;
      });
      /**在请求歌曲的时候,可能有的歌曲不可用,丢失。导致在播放器中的歌曲列表和页面展示的歌单存在差异,会出现实际的播放歌曲与要播放的歌曲不符的问题。
       * 用一次查找解决问题
       */
      for (let i in this.music) {
        if (this.music[i].index == index) {
          this.currentIndex = i;
          break; //break跳出循环------continue跳出本次循环
        }
      }
    });
  },

项目中存在的一些问题

1.歌手详情页面刷新没有数据:

问题原因 :路由跳转的时候我传入的是一个歌手信息对象,歌手详情的数据都是根据这个对象的信息,id获取的。

先给大家上代码吧

enterArtistDetail(artist) {
      this.$router.push({
        path: "/artist",
        query: {
          artist: artist
        }
      });
      this.$store.commit('addArtist',artist);
    }

我当初为什么这样写 :

(1)没选params当然是用params传参会报错啦,报错的原因:通过path进行传值的时候,报传的参数过大,而通过name进行传值确实能传,但是因为还有子路由,用name会导致后续无法重定向子路由。

(2)为什么不直接传个id然后再在路由中获取信息?,是因为我看了API文档发现并没有根据id获取歌手的基础信息接口。这也是搜索结果页面歌手头像都一样的原因,它给我的数据就是那样的,而且没有歌手基础信息的接口。

(3)额外用vuex保存歌手信息,是因为我当初测试的时候发现路由直接传参,子路由重定向的时候会存在拿不到传过来的值的问题。

关于本项目

本项目还有许多值得改进的地方,各位小伙伴们有好的解决方案及时在下面评论或者Pull Requests我, 让我们一起完善改进本项目

关于项目的不足各位小伙伴可以在lssues里提出,或者在下面评论,看到我都会逐渐改进。

项目下一步方向:由于音乐播放器是我自己封装的,还存在许多改进地方,和一些功能没有开发,所以目前打算主要改进播放器方面。

项目目录介绍

ea795e71fe6179777e4b006ebcc63792.png

3b9efd22f85a449f97add1d4a537a8d2.png

e58ffed7737d49f7297d2d4200c5d92c.png

92cf0bbd9396ff287f2df6427c4ce3b0.png

12a46250e28722e3f86adb645e477482.png

330f0edc1812c17739b7648ea55e0e99.png

49c76d50645f83d2d4d7ae8ed32f4b5a.png

655f6cb1506df7f9cc3ddec45bb103a0.png

音乐不能播放问题

1.要播放的音乐需要vip

2.要播放的音乐url出错,可在控制台查看log日志

运行

fds_music

Project setup

npm install

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

Customize configuration

See Configuration Reference.

470c5c34a9e362f1af929e2e8eea2e91.gif

cee7a25de7f5e7479f4edf82fe11ff17.gif

  • 新款SpringBoot在线教育平台开源了

  • 50份优秀Java求职者简历

  • 火速收藏,你们要的大屏幕模版来了

  • 2020年全网最全BAT笔试面试题打包分享

感谢点赞支持下哈 f99554dfd6c52589070ef98a1d8cd704.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值