完整展示:

image.pngimage.png

排行榜接口处理

在排行界面中,主要就是针对将获取到的排行数据进行渲染,但是网易云排行界面的接口数据随时都是动态变化内容具有不确定性,不一定匹配到我们指定的榜单名,所以不一定有rank字段,需要做判断。如果没有查找到对应的榜单应该把此数据删除。
image.png

榜单接口封装

  1. export const getTopListDetail = () => {
  2. return new Promise((resolve, reject) => {
  3. const category = {
  4. officialList: [
  5. { name: '飙升榜', id: 3 },
  6. { name: '新歌榜', id: 0 },
  7. { name: '原创榜', id: 2 },
  8. { name: '热歌榜', id: 1 }
  9. ],
  10. recList: [
  11. { name: '云音乐说唱榜', id: 23 },
  12. { name: '云音乐电音榜', id: 25 },
  13. { name: '云音乐欧美新歌榜', id: 32 },
  14. { name: '网络热歌榜', id: 26 },
  15. { name: '云音乐古风榜', id: 22 },
  16. { name: '听歌识曲榜', id: 24 }
  17. ],
  18. globalList: [
  19. { name: '中国新乡村音乐排行榜', id: 29 },
  20. { name: '美国Billboard榜', id: 6 },
  21. { name: 'UK排行榜周榜', id: 5 },
  22. { name: 'Beatport全球电子舞曲榜', id: 21 },
  23. { name: '日本Oricon榜', id: 10 },
  24. { name: '法国 NRJ Vos Hits 周榜', id: 8 }
  25. ],
  26. otherList: [
  27. { name: 'KTV唛榜', id: 7 },
  28. { name: '云音乐日语榜', id: 19 },
  29. { name: '云音乐摇滚榜', id: 27 },
  30. { name: '云音乐韩语榜', id: 28 },
  31. { name: '潜力爆款榜', id: 30 },
  32. { name: '云音乐欧美热歌榜', id: 31 }
  33. ],
  34. titles: { officialList: '官方榜', recList: '推荐榜', globalList: '全球榜', otherList: '更多榜单' }
  35. }
  36. Network.get('toplist/detail')
  37. .then(data => {
  38. data.list.forEach(obj => {
  39. let flag = false
  40. for (const key in category) {
  41. for (let i = 0; i < category[key].length; i++) {
  42. if (category[key][i].name === obj.name) {
  43. // 查找到该榜单,就添加到rank中
  44. category[key][i].rank = obj
  45. flag = true
  46. break
  47. }
  48. }
  49. if (flag) {
  50. break
  51. }
  52. }
  53. })
  54. // 校验category中的每一个榜单中是否含有rank
  55. for (const item in category) {
  56. if (item === 'titles') {
  57. continue
  58. }
  59. category[item] = category[item].filter(obj => obj.rank !== undefined)
  60. }
  61. resolve(category)
  62. })
  63. .catch(err => {
  64. reject(err)
  65. })
  66. })
  67. }

完整榜单:
image.png
榜单缺失情况处理:
image.png

搜索界面—节流指令

在搜索栏的搜索交互中,由于正常输入的情况会频繁触发搜索结果,因此需要对搜索栏做一个类似于百度搜索的节流处理。在组件中定义一个局部指令,定义每间隔1s触发一次指定的函数

  1. directives: {
  2. throttle: {
  3. // 节流指令
  4. inserted: function (el, binding) {
  5. let timerId = null
  6. let flag = true
  7. el.addEventListener('input', () => {
  8. if (!flag) return
  9. flag = false
  10. timerId && clearTimeout(timerId)
  11. timerId = setTimeout(function () {
  12. flag = true
  13. binding.value()
  14. }, 1000)
  15. })
  16. }
  17. }
  18. }
  1. <input v-throttle="search" type="text" placeholder="搜索歌曲、歌手、专辑" v-model="keywords">

搜索界面—非法关键字处理

对于一些无效或是非法的关键字也要进行一些处理,因为无效或非法关键字是没有搜索结果的,如果不及时处理,搜索列表的渲染就会出现问题。

  1. methods: {
  2. search () {
  3. if (this.keywords.length !== 0) {
  4. getSearchList({ keywords: this.keywords.trim() })
  5. .then(data => {
  6. if (data.result !== undefined) {
  7. if (data.result.songCount !== 0) {
  8. this.songs = data.result.songs
  9. }
  10. } else {
  11. this.songs = [
  12. {
  13. name: '暂未搜索结果',
  14. id: -1,
  15. artists: [{ name: '请重新输入' }]
  16. }
  17. ]
  18. }
  19. })
  20. .catch(err => {
  21. console.log(err)
  22. })
  23. }
  24. }
  25. }

image.png