基于Vue的音乐webapp

885 阅读2分钟

前言


基于Vue + Vue-Router + Vuex + axios + Less ,页面主要参照网易云音乐App , 数据来源于网易云音乐 Node.js API service NeteaseCloudMusicApi ,使用 vh 、vw 等视口单位 Viewport units 来适配移动端 ( 后续考虑用 rem 配合视口单位实现更好的适配 )

在线浏览

1核2G1Mbps带宽的渣ECS,加载可能比较慢

源码地址


github.com/Yaochentao/…

欢迎Star

项目部分截图

技术栈


  • Vue
  • Vue-Router
  • Vuex
  • Less
  • Axios
  • better-scroll

项目结构


│  .browserslistrc
│  .gitignore
│  babel.config.js
│  package-lock.json
│  package.json
│  postcss.config.js
│  README.md
│  vue.config.js     
└─src
    │  App.vue
    │  main.js
    │  registerServiceWorker.js
    │  router.js
    │  store.js
    ├─assets
    │  ├─css
    │  │ reset.css
    │  └─iconfont         
    └─components
        │  loading.vue
        │  progress-bar.vue
        │  scroll.vue
        ├─i-header
        │  i-header.vue
        ├─player
        │  player.vue
        ├─playingList
        │  playingList.vue
        ├─playList
        │  playList.vue
        ├─recommend
        │  recommend.vue
        │  slide.vue
        ├─search
        │  search-result.vue
        │  search.vue
        ├─singer
        │  singer.vue
        ├─song-list
        │  song-list.vue
        └─tab
           tab.vue

已实现的功能


  • 推荐页面

  • 歌单页面

  • 搜索功能

  • 歌手页面

  • 播放器(播放/暂停 ,切换歌曲 ,调整播放进度,歌词,播放模式切换 ,播放列表)

有待开发的功能


  • 登录功能(很多api都需要登录才能访问)
  • 私人FM
  • 每日推荐
  • 排行榜
  • 电台
  • 朋友动态

存在的bug


  • 播放需要vip的歌曲时没加判断,会产生无法播放且没提示的bug
  • 其他bug暂时还没发现,欢迎提出

开发中遇到的问题

  • 项目中搜索页有实时搜索功能,虽然加了防抖,但是极端情况下, 如请求两次搜索接口,第二次结果先返回,第一次结果后返回,会造成第二次返回的数据被覆盖的情况,从而视图显示的是第一次搜索的结果。 最后选择的解决方案: 发送请求后,暂存当时搜索框的值,与后端返回的值进行对比,若不同,则丢弃。(由于这里这个项目后端接口是github上开源的接口,故无法修改,使其返回接口的入参。但好在接口是GET请求的,可以通过ajax的responseURL解析URL中的入参获取到入参。需要注意的是url中的中文参数是url编码的,获取时候需要使用decodeURI()进行解码)
  • vuex对获取state或者getter之后最好深拷贝一份再进行操作(血的教训)
changeMode() {
    console.log('changemode')
    const mode = (this.$store.state.mode + 1) % 3;
    this.$store.commit('SET_PALY_MODE',mode);
    let list = null;
    let _list = this.sequenceList.slice(0);   //此处对this.sequenceList进行浅拷贝(因为这里只修改数组的顺序,不用修改里面深层次的对象或数组,故用浅拷贝就好)
    //   如直接将this.sequenceList传入shuffle函数会无意中修改state中的sequenceList
    if (mode === 2) {
        console.log('mode2')
        list = this.shuffle(_list);  //洗牌函数
    } else {
        console.log('mode01')
        list = _list
    }
    this.$store.commit('SET_PLAYLIST',list);
},
  • 组件获取dom和一般html元素获取dom

    <scroll ref='scroll-component'/>
    //若要访问引入的组件的对应的dom则需要访问其el属性this.$refs.scroll-component.$el
    
    
    <div ref='scroll-html'></div>
    //一般html元素只需this.$refs.scroll-html即可
    
  • 当用了keep-active组件时,会缓存不活动的组件实例,而不是销毁它们。故子组件不用时不会销毁,created等生命周期函数不会调用,actived()函数会被调用

感谢阅读~~~