image.pngimage.png

开发思路

这个界面相当于是主页上的一级路由,与推荐界面recommend.vue同级的,所以路由设计也相同。
点击两个不同的栏目会显示不同的数据。

可复用组件抽取

通过比较发现,最近收听界面中的数据内容区域与推荐页中的最新音乐区域是相同的,因此可以将推荐页中的最新音乐里面的组件进行抽取,形成通用组件。
image.png

通用组件SongListItem.vue

  1. <template>
  2. <ul class="song-list">
  3. <li class="item" v-for="value in songs" :key="value.id" @click="selectMusic(value.id)">
  4. <img v-lazy="value.picUrl" alt="">
  5. <div>
  6. <h3>{{value.name}}</h3>
  7. <p>{{value.singer}}</p>
  8. </div>
  9. </li>
  10. </ul>
  11. </template>
  12. <script>
  13. import { mapActions } from 'vuex'
  14. export default {
  15. name: 'SongListItem',
  16. props: {
  17. songs: {
  18. type: Array,
  19. default: () => [],
  20. required: true
  21. }
  22. },
  23. methods: {
  24. ...mapActions([
  25. 'setFullScreen',
  26. 'setMiniPlayer',
  27. 'setListPlayer',
  28. 'setSongDetail'
  29. ]),
  30. selectMusic (id) {
  31. this.setFullScreen(true)
  32. this.setMiniPlayer(false)
  33. this.setListPlayer(false)
  34. this.setSongDetail([id])
  35. }
  36. }
  37. }
  38. </script>
  39. <style scoped lang="scss">
  40. @import "../assets/css/mixin";
  41. @import "../assets/css/variable";
  42. .song-list{
  43. width: 100%;
  44. .item{
  45. padding: 0 20px;
  46. width: 100%;
  47. height: 150px;
  48. display: flex;
  49. align-items: center;
  50. margin-bottom: 20px;
  51. border-bottom: 1px solid #ccc;
  52. img{
  53. width: 120px;
  54. height: 120px;
  55. border-radius: 20px;
  56. margin-right: 20px;
  57. }
  58. div{
  59. width: 70%;
  60. h3{
  61. @include no-wrap();
  62. @include font_size($font_medium);
  63. @include font_color();
  64. }
  65. p{
  66. @include no-wrap();
  67. @include font_size($font_samll);
  68. opacity: 0.6;
  69. @include font_color();
  70. margin-top: 20px;
  71. }
  72. }
  73. }
  74. }
  75. </style>

将组件封装为以上格式,以后就直接在父组件中使用,父组件将获取到的数据通过songs字段传递给子组件,子组件中渲染songs数据中的内容(歌曲名称、歌曲封面、歌手名称)。

根据条件渲染

当前由于收听页有两个板块(收藏歌曲、最近收听)所以父组件需要在使用时根据传入的不同类型来渲染不同数据,收藏歌曲的数据内容和最近收听的数据内容在之前的播放器环节中已经开发好保存在VuexlocalStorage中,数据名分别为favoriteListhistoryList。我们只需要针对收听页在Vuex中管理一个全局状态,就是当前选择的板块类型,取名为switchNum,取值为0代表收藏歌曲栏目,取值为1代表最近收听。
image.png
父组件中按条件传入值即可:

  1. <div class="bottom-wrapper" ref="accountWrapper">
  2. <ScrollView ref="scrollView">
  3. <template #scorllContent>
  4. <SongListItem :songs="switchNum === 0 ? favoriteList : historyList"></SongListItem>
  5. </template>
  6. </ScrollView>
  7. </div>

不建议调用本地缓存数据中歌曲的URL

虽然在收听页面是通过获取缓存的数据来渲染的,但是在播放歌曲的时候建议这里必须去反复调用api获取歌曲文件资源,不能直接取出Vuex中或者localstorage已有的歌曲url,因为网易云获取的歌曲链接具有时效性,也就是保存在历史记录中的歌曲url有可能已经过期失效。这样在播放歌曲的时候会导致一些未知的错误。
image.png
image.png