微信小程序实战教程:模仿—网易云音乐(一)

来源:互联网 发布: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
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
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

阅读全文
0 0
原创粉丝点击