微信小程序实战教程:模仿—网易云音乐(一)
来源:互联网 发布:iphone中的照片导入mac 编辑:程序博客网 时间:2024/06/09 16:06
初窥
todo:
- 添加音乐到收藏(最近)列表
- 歌词滚动
从一个hello world开始
微信开发者工具生成 目录如下:
.|-- app.js|-- app.json|-- app.wxss|-- pages | |-- index # 主页| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| `-- log # 日志页面| | |-- log.js| | |-- log.json| | |-- log.wxml| | `-- log.wxss`-- utils # 工具 `-- util.js
大体为:
每一个page即是一个页面文件 ,每个页面有一个js/wxml/wxss/json文件 规定:描述页面的这四个文件必须具有相同的路径与文件名。
全局下同路,为公共的逻辑,样式,配置
与html不同:用view text navigator 代替 div span a
开发者文档走马观花
app.json: 注册pages window tabBar networkTimeout
组件说明
*.js: 作为逻辑层 与wxml交互 有着丰富的
网络,
媒体,
文件,
数据缓存,
位置,
设备,
界面…的api
官方文档
*.wxml: 数据驱动的视图层 + 微信提供了大量的组件 表单 导航 媒体 …
官方组件不够,weui来凑
weui为小程序提供了 weui.wxcss 但大多是造官方组件的轮子
这里精选,也算是补充两个常用组件
对于小程序没有DOM操作 不熟悉mvvm思想的同学 是个很好的入门
navbar
<!-- wxml --><view class="weui-tab"> <view class="weui-navbar"> <block wx:for="{{tabs}}" wx:key="*this"> <view id="{{index}}" class="weui-navbar__item {{activeIndex == index ? 'weui-bar__item_on' : ''}}" bindtap="tabClick"> <view class="weui-navbar__title">{{item}}</view> </view> </block> <view class="weui-navbar__slider" style="left: {{sliderLeft}}px; transform: translateX({{sliderOffset}}px); -webkit-transform: translateX({{sliderOffset}}px);"></view> </view> <view class="weui-tab__panel"> <view class="weui-tab__content" hidden="{{activeIndex != 0}}">选项一的内容</view> <view class="weui-tab__content" hidden="{{activeIndex != 1}}">选项二的内容</view> <view class="weui-tab__content" hidden="{{activeIndex != 2}}">选项三的内容</view> </view> </view>
block渲染data里面的四个tabs,slider为激活tab选项时候的表现,panel为内容面板
//jsvar sliderWidth = 96; // 需要设置slider的宽度,用于计算中间位置Page({ data: { tabs: ["选项一", "选项二", "选项三"], activeIndex: 1, sliderOffset: 0, sliderLeft: 0 }, onLoad: function () { var that = this; wx.getSystemInfo({ success: function(res) { that.setData({ sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2, sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex }); } }); }, tabClick: function (e) { this.setData({ sliderOffset: e.currentTarget.offsetLeft, activeIndex: e.currentTarget.id }); }});
了解mvvm思想的同学不难看出 通过tabs数组渲染出来选项后每次点击获取id 然后通过设置hidden显示或隐藏
searchbar
<view class="weui-search-bar"> <view class="weui-search-bar__form"> <view class="weui-search-bar__box"> <icon class="weui-icon-search_in-box" type="search" size="14"></icon> <input type="text" class="weui-search-bar__input" placeholder="搜索" value="{{inputVal}}" focus="{{inputShowed}}" bindinput="inputTyping" /> <view class="weui-icon-clear" wx:if="{{inputVal.length > 0}}" bindtap="clearInput"> <icon type="clear" size="14"></icon> </view> </view> <label class="weui-search-bar__label" hidden="{{inputShowed}}" bindtap="showInput"> <icon class="weui-icon-search" type="search" size="14"></icon> <view class="weui-search-bar__text">搜索</view> </label> </view> <view class="weui-search-bar__cancel-btn" hidden="{{!inputShowed}}" bindtap="hideInput">取消</view> </view> <view class="weui-cells searchbar-result" wx:if="{{inputVal.length > 0}}"> <navigator url="" class="weui-cell" hover-class="weui-cell_active"> <view class="weui-cell__bd"> <view>实时搜索文本</view> </view> </navigator> </view>
一个input输入框+一个搜索label+一个清楚内容的icon + 取消按钮
Page({ data: { inputShowed: false, inputVal: "" }, showInput: function () { this.setData({ inputShowed: true }); }, hideInput: function () { this.setData({ inputVal: "", inputShowed: false }); }, clearInput: function () { this.setData({ inputVal: "" }); }, inputTyping: function (e) { this.setData({ inputVal: e.detail.value }); }});
input上面有一层label 通过Page里面状态的改变而操作其wxml状态的改变
不难体会到:小程序和Vue的思想还是挺接近的
站在巨人的肩膀上–云音乐api
—获取云音乐api
巨人的源github项目
在此我将他部署到leancloud上
即可在线访问,免去烦人的本地localhost启动,在线url
http://neteasemusic.leanapp.cn
调用例子:
http://neteasemusic.leanapp.c…海阔天空
http://neteasemusic.leanapp.c…
具体参考api
详细文档
一切具备 只欠东风
生成目录本文讲解核心内容音乐的播放,读者可自己实现其余页面。
.|-- app.js|-- app.json|-- app.wxss|-- common.js #公用js|-- images #存放项目图片|-- style| |-- weui.wxss # 引入weui样式 万一你自己不想写css样式呢|-- pages| |-- find # 发现音乐| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| |--my # 我的音乐| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| |--now # 正在播放| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| |--account # 账号| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| |-- index # 主页| | |-- index.js| | |-- index.json| | |-- index.wxml| | `-- index.wxss| `-- log # 日志页面`-- utils # 工具 `-- util.js
请先在在app.json中注册页面,设置navigation,配置tabbar
{ "pages":[ "pages/find/index", "pages/my/index", "pages/now/index", "pages/account/index", "pages/index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#D43C33", "navigationBarTitleText": "网易云音乐", "navigationBarTextStyle":"white", "backgroundColor": "#FBFCFD" }, "tabBar": { "backgroundColor":"#2A2C2E", "color": "#a7a7a7", "selectedColor": "#ffffff", "list": [{ "iconPath":"./images/find.png", "selectedIconPath":"./images/find1.png", "pagePath":"pages/find/index", "text": "发现音乐" }, { "iconPath":"./images/my.png", "selectedIconPath":"./images/my1.png", "pagePath": "pages/my/index", "text": "我的音乐" }, { "iconPath":"./images/now.png", "selectedIconPath":"./images/now1.png", "pagePath": "pages/now/index", "text": "正在播放" }, { "iconPath":"./images/account.png", "selectedIconPath":"./images/account1.png", "pagePath": "pages/account/index", "text": "账号" }] }}
发现音乐
布局分为搜索框,navbar,swiper滑动,三列,以及两行三列构成
tips:小程序中flex布局基本无兼容性问题 ,可大胆使用
前三个可用上文提到的组件和小程序swiper组件快速完成,
对于搜索功能
我们在搜索input上绑定一个inputTyping事件,这样每次键入完毕都可以得到结果,然后我们直接请求api
//index.js//获取应用实例// 个人网易云音乐 ID 66919655var app = getApp()Page({ data: { searchReault: [] }, //绑定事件 inputTyping: function (e) { let that = this console.log(e.detail) this.setData({ inputVal: e.detail.value }); wx.request({ url: 'http://neteasemusic.leanapp.cn/search', data: { keywords: e.detail.value }, method: 'GET', success: function (res) { let temp = [] if(!res.data.result.songs){ return ; } //遍历数据 res.data.result.songs.forEach((song, index) => { temp.push({ id: song.id, name: song.name, mp3Url: song.mp3Url, picUrl: song.album.picUrl, singer: song.artists[0].name }) //设置数据 that.setData({ searchReault: temp }) }) // 存入搜索的结果进缓存 wx.setStorage({ key:"searchReault", data:temp }) } }) }});
data里面的searchReault数组存入搜索结果,发起一个wx.request,用GET方式传入参数,组织好json后设置data,然后将搜索结果存入本地缓存
wxml渲染searchReault:
并且自定义data属性,navigator的打开方式为tab切换open-type=”switchTab” ,绑定一个tonow事件bindtap=”tonow”
<block wx:for="{{searchReault}}" wx:key="item" style="overflow-y: scroll;"> <navigator url="../now/index" class="weui-cell" hover-class="weui-cell_active" data-id="{{item.id}}" data-name="{{item.name}}" data-songUrl="{{item.mp3Url}}" data-picUrl="{{item.picUrl}}" data-singer="{{item.singer}}" open-type="switchTab" bindtap="tonow"> <view class="weui-cell__bd"> <view class="song-name">{{item.name}} <text class="song-singer">{{item.singer}}</text> </view> </view> </navigator></block>
在tonow事件中,获取当前的歌曲
tonow: function (event) { let songData = { id: event.currentTarget.dataset.id, name: event.currentTarget.dataset.name, mp3Url: event.currentTarget.dataset.songurl, picUrl: event.currentTarget.dataset.picurl, singer: event.currentTarget.dataset.singer } // 将当前点击的歌曲保存在缓存中 wx.setStorageSync('clickdata', songData) wx.switchTab({ url: '../now/index' }) }
正在播放
布局:歌曲封面,滑动条上下为操作按钮,
封面在采用圆角,rotate,transition既可以
滑动快进:在滑动条上绑定事件 slider3change
//滑动 歌曲快进function sliderToseek(e, cb) { wx.getBackgroundAudioPlayerState({ success: function (res) { var dataUrl = res.dataUrl var duration = res.duration let val = e.detail.value let cal = val * duration / 100 cb && cb(dataUrl, cal); } })}//分隔 在page中调用 slider3change: function (e) { sliderToseek(e, function (dataUrl, cal) { wx.playBackgroundAudio({ dataUrl: dataUrl }) wx.seekBackgroundAudio({ position: cal }) }) },
一个自定义的sliderToseek函数:
参数e 可以获取滑动的值,获取正在播放的音乐信息成功后执行回调函数1->播放 回调函数2->跳到指定位置;
拆分歌词:
在api中得到的歌词:”[00:00.00] 作曲 : 黄家驹 [00:01.00] 作词 : 黄家驹 [00:18.580]今天我 寒夜里看雪飘过 [00:25.050]怀着冷却了的心窝漂远方 [00:30.990]风雨里追赶 ”
在page外定义函数:
以]划分数组 第二部分就是歌词内容:item.split(‘]’)[1] 第一部分即为对应的时间:item.split(‘]’)[0]
// 获取歌词function getlyric(id,cb) { console.log('id:',id) let url = `http://neteasemusic.leanapp.cn/lyric` wx.request({ url: url, data: { id: id }, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT // header: {}, // 设置请求的 header success: function (res) { // success if (!res.data.lrc.lyric) return false; let lyric = res.data.lrc.lyric let timearr = lyric.split('[') let obj = {} let lyricArr=[] // seek 为键 歌词为value timearr.forEach((item) => { let key = parseInt(item.split(']')[0].split(':')[0]) * 60 + parseInt(item.split(']')[0].split(':')[1]) let val = item.split(']')[1] obj[key] = val }) for(let key in obj){ // obj[key] = obj[key].split('\n')[0] lyricArr.push(obj[key]) } cb&&cb(obj,lyricArr) }, fail: function (res) { // fail }, complete: function (res) { // complete } })}
在page中调用:传入歌曲ID(上文我们已经存入缓存,在缓存中取出即可),和将其设置在data的回调
getlyric(id,function(data, lyricArr){ that.setData({ lyricobj:data, lyricArr:lyricArr }) })
原文地址:
http://www.wxapp-union.com/article-2270-1.html?utm_source=geek.csdn.net
- 微信小程序实战教程:模仿—网易云音乐(一)
- 微信小程序实战教程:模仿—网易云音乐(二)
- Qt模仿网易云音乐
- 微信小程序-网易云音乐
- 模仿网易云音乐移动端播放器
- 一个模仿网易云音乐的豆瓣开源项目
- [干货教程]仿网易云课堂微信小程序开发实战经验
- 网易云音乐Ubuntu 16.04安装教程
- 高仿网易云音乐一(可扫描本地音乐播放)
- python爬虫入门 实战(三)---爬网易云音乐热门评论
- Python3爬虫抓取网易云音乐热评实战
- 项目实战 | Python开发网易云音乐插件
- 模仿网易新闻客户端(RSS版)(一)
- 模仿网易新闻客户端(RSS版)(一)
- 模仿网易新闻客户端(RSS版)(一)
- 模仿网易新闻客户端(RSS版)(一)
- 模仿网易新闻客户端(RSS版)(一)
- 《易读》一个模仿网易云音乐UI,Rxjava+Retrofit+dagger2+MVP的开源项目
- java反射机制
- Mac Nginx 配置 Tomcat 配置 jdk环境变量 Nginx部署服务遇到的坑(2)
- windows下git保存全局账号密码. git bash
- 非递归先序遍历二叉树
- 传统营销法则下举步维艰?读邮件营销四大思考,开启第二次营销生命!
- 微信小程序实战教程:模仿—网易云音乐(一)
- iOS系统版本判断
- POI的一些运用
- Springboot+SpringData+jpa
- vue开发:生成token保存在客户端localStorage中
- GSMS-华为应急通讯完美版 ISO文件下载
- 为什么要在密码里加点“盐”
- SQL Server将表数据移动到新的文件/文件组
- JS 跨域问题和解决方案