简单的仿网易云音乐小程序(一)

  • 前言
  • 思维图
  • 注意事项
    • 虚拟机调试
    • 真机调试
  • 主页面
    • 搜索框
    • 歌单列表
      • 歌单模版
      • wxs filter
    • 页面逻辑
  • 等待搜索页面
    • 搜索框
      • clearValue
      • startSearch
      • inputC
      • back
    • 热门搜索标签
      • 定义切换组件
      • 使用数据渲染不同页面
  • 小结

前言

今天我们开始学习简单的仿网易云音乐小程序,该小程序由Github提供,并具有网络请求和音乐播放等经典基础功能。


思维图


在上述的思维图中,每当点击歌曲列表中的歌曲时,均会跳转到音乐播放界面。


注意事项

由于该小程序使用到了网络请求功能,故需要在开发者工具中进行设置。如果不设置,会出现以下情况。

虚拟机调试

如果仅仅只是想在虚拟机上进行网络请求功能的调试,要解决上述问题很简单。

  1. 打开开发者工具中右上角的详情页面。
  2. 将本地设置中的红箭头指视处打勾

真机调试

当你想使用真机进行调试时,上述办法就行不通了,需要到微信小程序的官网上进行设置。

  1. 登陆小程序官网,进入到管理页面,并点击开发选项卡。
  2. 开发页面中点开开发设置,找到服务器域名模块,添加上网络请求的地址即可。

主页面

搜索框

搜索框位于页面的顶部,当用户点击时,自动跳转到等待搜索页面。故很容易想到这是一个导航跳转功能。

<navigator class='topsearchLeft' url='../search/search'><view class='iconfont icon-sousuo sousuo'></view><text>搜索</text>
</navigator>

上述代码中,设置了一个导航组件,当点击该组件时,跳转到url对应的页面中。

歌单列表

歌单列表用到了我们之前尚未学习过的新只是,即导入wxml的模版文件。使用模版文件也很好理解,因为歌单列表会重复的使用,当将该页面独立为一个模版组件后,调用起来将会非常的方便,也省略了很多冗余的代码。

<!-- 从文件中导入模版wxml -->
<import src="./template/boutiqueItem" />
<view class='BoutiqueList'><!-- block 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。 --><!-- for循环遍历音乐数据 --><block wx:for="{{musicList}}" wx:key="index"><!-- 将每一项数据输送给模版进行页面的渲染 --><!-- 使用名字为ListItem的模版 --><template is="ListItem" data="{{item}}" /></block>
</view>

这个模版在后续代码中均有使用,故我们在这进行学习

歌单模版

本小程序使用的歌单模版为一个单个的wxml文件,其他的wxml可以使用相对路径的方法对其进行调用。

模版文件存放在template文件夹下,WXML提供模板template,可以在模板中定义代码片段,然后在不同的地方调用。该模版内容没有特别新奇的地方,故没有特别添加上注释

<wxs src="../../../utils/filter.wxs" module="filter" />
<template name="ListItem"><!-- 这里的item是调用该template输出的data值 --><view class='musicItem' bindtap='getdetail' data-id='{{item.id}}'><view class='musicItem_left'><image class='musicItemImg' src='{{item.coverImgUrl}}' alt='' lazy-load="true" mode="scaleToFill"></image><view class='playCount_box'><view class='iconfont icon-ttpod playCount_icon'></view><!-- 使用wxs中的内容 --><text class='playCount'>{{filter.over10000(item.playCount)}}</text></view></view><view class='musicItem_right'><text class='musicItem_name'>{{item.name}}</text><text class='musicItem_nickname'>by {{item.creator.nickname}}</text><view class='musicItem_tag'><text class='musicItem_tag_b'>{{item.tags[0]}}</text><text class='musicItem_copywriter'>{{item.copywriter}}</text></view></view></view>
</template>

唯一值得留意的是上述代码的第一行。WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。其中的module为该标签的模块名。此外,getdetail为点击每个item的响应函数

// 跳转到musiclist页面
// 在musiclist页面中的load函数,可以获取到该跳转传入的id
getdetail: function(options) {wx.navigateTo({url: '../../../../musicList/musicList?musicListID=' + options.currentTarget.dataset.id})}

wxs filter

接下来我们看看这个wxs这个被命名为filter的组件在做些什么(直观上来看,它是作为一个数据的过滤器)

// 超出1万和1亿的过滤器
var over10000 = function (num) {if (num < 10000) {return num;} else if (num >= 100000000) {return parseInt(num / 100000000) + "亿";} else {return parseInt(num / 10000) + "万";}
}
module.exports = {over10000: over10000,
}

我们贴出了上述代码中仅使用到的内容,即通过num来返回不通格式的数据,以免数据太多,显示太难看。

页面逻辑

最后我们来看看主页面的页面逻辑。

  1. 导入网络请求的api
  2. 初始化网络请求的函数
  3. 当页面加载时调用网络请求的函数
  4. 当滑动到页面底部时,再次发动请求
// 1
import api from '../../utils/api.js';
// 2
getBoutiqueList() {// 调用api中的函数api.getBoutiqueList({// 配置每次请求数据的条数data: {limit: this.data.limit},// 请求成功,返回音乐列表success: resp => {this.setData({musicList: resp.data.playlists})}})},
// 3// 生命周期函数--监听页面加载onLoad(e) {this.getBoutiqueList()},
// 4
// 页面上拉触底事件的处理函数
onReachBottom: function() {this.setData({limit: this.data.limit + 10})this.getBoutiqueList()
},

等待搜索页面

搜索框

页面顶部的搜索框的页面代码如下

 <view class='topSearch'><!-- 构建一个表单组件,reset绑定的响应函数为clearValue --><form bindreset="clearValue" class='inputform'><!-- 构建输入控件placeholder-class: 指定 placeholder 的样式类confirm-type: 设置键盘右下角按钮的文字,仅在type='text'时生效bindconfirm: 点击按钮后的响应函数bindinput: 输入时触发 --><input class='inputB' placeholder-class="holderInput" placeholder="输入您想要搜索的内容" auto-focus confirm-type="search" bindconfirm="startSearch" bindinput="inputC" value="{{keywords}}"></input><view class='iconfont icon-sousuo sousuo'></view><!-- 小叉叉按钮,用来清楚输入框的值 --><!-- 有值就显示,无值就不显示 --><button class='iconfont icon-shanchu clearBtn' formType="reset" wx:if="{{haveValue}}"></button></form><!-- 取消按钮,响应函数为back --><view class='cansBtn' bindtap='back'>取消</view></view>

其实搜索框就是一个添加了多个样式和功能的输入框。接下来,我们依次看看响应函数。

clearValue

// 清除vlaue
clearValue() {this.setData({haveValue: false,showHotsearch: true})
},

该响应函数很简单,就是将haveValue标志为设置为false,表示输入框没有值;将showHotsearch设置为true,表示不显示搜索内容,只显示热门搜索。

startSearch

首先给出响应函数

// 搜索框输入后按搜索按钮时的搜索,参数都应是默认值
startSearch(opt) {let keywords = '';// 如果输入框没有值if (!opt.detail.value){keywords = 'hello word'//opt.currentTarget.dataset.value}else{keywords = opt.detail.value}// 搜索前先清空每个数组this.setData({haveValue: true,keywords: keywords,songArr: [],   //歌曲musicListArr: [],   //歌单singerArr: [],   //歌手videoArr: [], //视频})// 执行搜索函数this.search();
},

我们看到,这个响应函数首先是对数据做了一个清洗和出事话,然后在执行搜索函数

// 实际进行搜索的函数
search() {// 调用api中对函数api.searchStart({// 需要对参数为,// 关键字,返回内容对条数,搜索的类型data: {keywords: this.data.keywords,limit: this.data.limit,type: this.data.searchType,},// 搜索到结果后的回调success: resp => {// 使用搜索的类型来判断内容switch (this.data.searchType) {// 歌曲列表case 1:this.setData({songArr: resp.data.result.songs,showHotsearch: false})break;// 歌单列表case 1000:this.setData({musicListArr: resp.data.result.playlists,showHotsearch: false})break;// 歌手列表case 100:this.setData({singerArr: resp.data.result.artists,showHotsearch: false})break;// 视频列表case 1004:this.setData({videoArr: resp.data.result.mvs,showHotsearch: false})break;}}})
},

基本没什么好说的,就是调用网络请求,然后通过类型类判断更新的数据。当数据得到更新后,页面自然也就发生了变化

inputC

就是一个在输入过程的监控

// 输入中
inputC(opt) {// 判断输入的数据长度是否大于0// 并用此来设置标志位if (opt.detail.value.length) {this.setData({haveValue: true})} else {this.setData({haveValue: false,showHotsearch: true})}
},

back

这个就更简单了,返回上一级

  // 返回上一页back() {wx.navigateBack()},

热门搜索标签

当未发生搜索行为,即showHotsearchtrue时,页面显示的是热门搜索标签

<!-- 用showHotsearch来判断当前该展示搜索结构还是展示热门搜素标签 --><view class='searchBottom' wx:if="{{showHotsearch}}"><view class='hotsearchtitle'>热门搜索</view><!-- 遍历热门搜索数据,并渲染到页面 --><block wx:for="{{hotsearch}}" wx:key="index"><text class='hotsearchitem' bindtap='startSearch' data-value='{{item.name}}'>{{item.name}}</text></block></view>

当搜索行为完成后,将会显示单曲歌单歌手视频的页面,这四个界面可通过点击来进行切换。

定义切换组件

<view class='searchNav'><!-- 页面内容上端,搜索框下端的内容切换组件 --><!-- 响应函数均为changeNav --><text bindtap='changeNav' data-type='1'>单曲</text><text bindtap='changeNav' data-type='1000'>歌单</text><text bindtap='changeNav' data-type='100'>歌手</text><text bindtap='changeNav' data-type='1004'>视频</text><view class='navLine' style='transform:translateX({{navLinePosition}})'></view>
</view>

切换组件的响应函数,因为大都一样,故只给出一小段

 // nav点击
changeNav(opt) {// 根据点击到的组件的类型进行数据的更新switch (opt.currentTarget.dataset.type) {case '1':// 主要就是更新下划线// 搜索类型// 下划线的位置this.setData({navLinePosition: '53rpx',searchType: 1,positionLeft: 0})// 重新执行搜索if (!this.data.songArr.length) {this.search();}break;

使用数据渲染不同页面

这里就是简单的遍历不同的数据,然后对页面进行渲染。

<view class='songBox centeritem' style='height:{{innerHeight}}rpx'><block wx:for="{{songArr}}" wx:key="index"><template is="songList" data="{{item}}" /></block>
</view>

可以看到,这里也适用了模版。具体来说,单曲,歌手,歌曲列表,视频列表都用了不同的模版,但是都大同小异。值得一看的是模版中的点击响应函数,在此用点击播放歌曲为例

//跳转到播放页
playSong(opt) {// 获取歌曲细节信息api.getSongDetai({data: {ids: opt.currentTarget.dataset.itemid},success: resp => {app.globalData.musicListArr = resp.data.songs;// 跳转到歌曲播放界面wx.navigateTo({url: '../audioPage/audioPage?musicindex=0&duration=' + opt.currentTarget.dataset.duration,})}})
},

小结

这篇博文中,主要对主页面和搜索界面进行了学习。其中最值得注意的就是网络请求的使用和模版的使用。接下来,我们将学习其他页面,并学习这篇文章中跳过的api的源码部分。

简单的仿网易云音乐小程序(一)相关推荐

  1. 简单的仿网易云音乐小程序(总结)

    简单的仿网易云音乐小程序(总结) 这个小程序学到了以下知识点 配置网络请求 进行网络请求 进行音乐播放 进行模版使用 各种页面触发事件 输入框的使用 简单的自定义tab页面切换 导航的数据传输

  2. 网易云音乐小程序,带后台(SpringBoot)

    目录 1.简介 2.技术栈 3.环境 4.项目后台配置 5.项目展示 6.下载地址 1.简介 此系统是仿网易云音乐 网易云音乐是一款专注于发现与分享的音乐产品,依托专业音乐人.DJ.好友推荐及社交功能 ...

  3. taro 重新加载小程序_taro-music一款开源网易云音乐小程序

    简介 taro-music 是基于taro + taro-ui + redux + react-hooks + typescript 开发的网易云音乐小程序,目前正在使用react-hooks重构中. ...

  4. 网易云音乐小程序案例分享 附完整代码

    todo: 添加音乐到收藏(最近)列表 歌词滚动 从一个 hello world 开始 微信开发者工具生成 目录如下: . |-- app.js |-- app.json |-- app.wxss | ...

  5. 网易云音乐小程序登录接口显示400,拥挤问题解决

    有在做网易云登录接口的小伙伴会发现自己会出现如下问题 解决办法: 用这个接口:https://neteasecloudmusicapi.js.org/#/ 配置好,先cmd,再npm i,如果出现np ...

  6. 网易云音乐小程序 笔记

    小程序750px html 双引号 js 单引号 flex布局:弹性盒子 授权动作只发生一次 获取用户信息 flex-direction: column; // 修改flex主轴x修改为y lign- ...

  7. 网易云音乐排行榜接口取消后解决方法(网易云音乐小程序)

    解决办法: 结合"所有榜单"和"获取歌单详情"两个api获取.因为获取歌单详情api只能获取单个歌单的内容,所以要先获得多个歌单id. 完整代码: let to ...

  8. 微信小程序仿网易云音乐(使用云开发,提供源码)

    微信小程序仿网易云音乐(使用云开发,提供源码)!!!!!!!!!!! 源码: 链接:https://pan.baidu.com/s/1z_ZnRVbT4vjEENimi8yBQQ 提取码:u0o3 一 ...

  9. 仿网易云音乐(微信小程序版)

    项目部分截图(Gif) 前言 前一阵子学习了微信小程序,为了巩固所学的知识和提高实战经验,决定自己手撸一款小程序.因为听歌一直在用网易云音乐,所以突发奇想就做一款仿网易云音乐的小程序吧!开发中遇到了很 ...

最新文章

  1. 独家 | 手把手教TensorFlow(附代码)
  2. “金财工程”网络安全 五
  3. javafx树视图加选框_JavaFX缺少的功能调查:表视图
  4. redis nginx session tomcat
  5. linux搭建redis
  6. idea tomcat配置
  7. Python出入库简洁系统
  8. 语义分割之原图与mask的可视化
  9. 在ASP.NET的复合组件中实现冒泡处理机制
  10. 语音控制系统(1)-----项目前言
  11. 企业微信代开发获取应用Secret
  12. 马化腾:与CNTV合作是产业的延展
  13. 国外广告联盟:玩转国外CPC网站作弊
  14. 运动模糊/拖影的原因分析
  15. python3遍历目录查找文件
  16. YOLO中对IOU、GIOU、DIOU、CIOU的理解
  17. java pv uv_前端数据收集(pv/uv)
  18. Golang bytes源码分析
  19. 啊哈添柴挑战Java1827. 顺序输出(难)
  20. WPS 中添加MathType插件

热门文章

  1. m1芯片能装mysql_Apple M1芯片电脑 软件兼容情况
  2. python列表排序不改变顺序
  3. 瘦客户端与胖客户端的理解
  4. 后台管理系统移动端适配解决方案
  5. 每日一题-leetcode 365. 水壶问题
  6. 手把手教你如何做电视直播
  7. html5游戏制作raf,HTML5之弧度角度与sincos(五角星绘制)、Canvas图形组合、阴影、图像绘制及createJS应用...
  8. HDU 3966 POJ 3237 HYSBZ 2243 HRBUST 2064 树链剖分
  9. 阿里巴巴arthas诊断工具使用介绍
  10. [pwnable.kr]uaf