【WEB】vue2.0开发音乐播放器
来源:互联网 发布:心理教学软件 编辑:程序博客网 时间:2024/06/06 16:07
1.安装模版
vue init webpack vue-music
注:vue脚手架可以帮我们初始化webpack的配置
初始化后目录如下:
//所有开发是基于修改src的文件
api:用来放跟后端请求相关
common:通用的静态资源(fonts/image/js/stylus)
components:通用组件
router:路由相关组件
store:vuex相关代码
App.vue:模版
main.js:文件入口,用来渲染app的文件
stylus文件里的变量定义:
// 颜色定义规范$color-background = #222$color-background-d = rgba(0, 0, 0, 0.3)$color-highlight-background = #333$color-dialog-background = #666$color-theme = #ffcd32$color-theme-d = rgba(255, 205, 49, 0.5)$color-sub-theme = #d93f30$color-text = #fff$color-text-d = rgba(255, 255, 255, 0.3)$color-text-l = rgba(255, 255, 255, 0.5)$color-text-ll = rgba(255, 255, 255, 0.8)//字体定义规范$font-size-small-s = 10px$font-size-small = 12px$font-size-medium = 14px$font-size-medium-x = 16px$font-size-large = 18px$font-size-large-x = 22px
在其他的styl文件中,通过@import “./XX.styl”
在main.js中:import 'common/stylus/index.styl'
注:有几处需要修改:
1.在package.json里,添加stylus和stylus-loader依赖(npm install)
2.在webpack.base.conf.js里,配置路径别名
resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': resolve('src'), 'common': resolve('src/common'), 'components': resolve('src/components'), 'base': resolve('src/base'), 'api': resolve('src/api') } },
启动项目:npm run dev
2.开发tab界面并配置路由
1.components:
新建m-header文件:
<template> <div class="m-header"> <div class="icon"></div> <h1 class="text">Chicken Music</h1> <router-link tag="div" class="mine" to="/user"> <i class="icon-mine"></i> </router-link> </div></template><script type="text/ecmascript-6"> export default {}</script><style scoped lang="stylus" rel="stylesheet/stylus"> @import "~common/stylus/variable" @import "~common/stylus/mixin" .m-header position: relative height: 44px text-align: center color: $color-theme font-size: 0 .icon display: inline-block vertical-align: top margin-top: 6px width: 30px height: 32px margin-right: 9px bg-image('logo') background-size: 30px 32px .text display: inline-block vertical-align: top line-height: 44px font-size: $font-size-large .mine position: absolute top: 0 right: 0 .icon-mine display: block padding: 12px font-size: 20px color: $color-theme</style>
在app.vue里面
<template> <div id="app" @touchmove.prevent> <m-header></m-header><!--放入模版中--> <tab></tab> <keep-alive><!--可以把dom缓存到内存中--> <router-view></router-view> </keep-alive> <player></player> </div></template><script type="text/ecmascript-6"> import MHeader from 'components/m-header/m-header'//引入包 import Player from 'components/player/player' import Tab from 'components/tab/tab' export default { components: { MHeader,//引入组件 Tab, Player } }</script><style scoped lang="stylus" rel="stylesheet/stylus"></style>
2.配置router里的index.js
export default new Router({routes:[{ path:'/', component:Recommend//注意拼写},{ path:'/recommend', component:Recommend},{ ...}]})
之后引入到vue实例里
在main.js中
/* eslint-disable no-new */new Vue({ el: '#app', router, render: h => h(App)})
下一步,是使用这个路由:
在APP.VUE中
<router-view></router-view>
下一步,写导航栏
<template> <div class="tab"> <router-link tag="div" class="tab-item" to="/recommend"> <span class="tab-link">推荐</span> </router-link><!--tag标示把它渲染成什么标签,to指向了需要跳转的路由--> <router-link tag="div" class="tab-item" to="/singer"> <span class="tab-link">歌手</span> </router-link> <router-link tag="div" class="tab-item" to="/rank"> <span class="tab-link">排行 </span> </router-link> <router-link tag="div" class="tab-item" to="/search"> <span class="tab-link">搜索</span> </router-link> </div></template>
加入到app.vue里
<tab></tab>
3.推荐界面开发
1.数据来源:qq音乐。jsonp:
github.com/webmodules/jsonp:学习index.js源码
使用npm 安装
在 common里jsonp.js
import originJsonp from 'jsonp'export default function jsonp(url, data, option) { url += (url.indexOf('?') < 0 ? '?' : '&') + param(data) return new Promise((resolve, reject) => { originJsonp(url, option, (err, data) => { if (!err) { resolve(data) } else { reject(err) } }) })}export function param(data) { let url = '' for (var k in data) { let value = data[k] !== undefined ? data[k] : '' url += '&' + k + '=' + encodeURIComponent(value) } return url ? url.substring(1) : ''}
在api封装recommond.js方法。
export function getRecommend() { const url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg' const data = Object.assign({}, commonParams, { platform: 'h5', uin: 0, needNewCode: 1 }) return jsonp(url, data, options)}
在recommand.vue中
<script type="text/ecmascript-6"> import Slider from 'base/slider/slider' import Loading from 'base/loading/loading' import Scroll from 'base/scroll/scroll' import {getRecommend, getDiscList} from 'api/recommend' import {playlistMixin} from 'common/js/mixin' import {ERR_OK} from 'api/config' import {mapMutations} from 'vuex' export default { mixins: [playlistMixin], data() { return { recommends: [], discList: [] } }, created() { this._getRecommend() this._getDiscList() }, methods: { handlePlaylist(playlist) { const bottom = playlist.length > 0 ? '60px' : '' this.$refs.recommend.style.bottom = bottom this.$refs.scroll.refresh() }, loadImage() { if (!this.checkloaded) { this.checkloaded = true this.$refs.scroll.refresh() } }, selectItem(item) { this.$router.push({ path: `/recommend/${item.dissid}` }) this.setDisc(item) }, _getRecommend() { getRecommend().then((res) => { if (res.code === ERR_OK) { this.recommends = res.data.slider } }) }, _getDiscList() { getDiscList().then((res) => { if (res.code === ERR_OK) { this.discList = res.data.list } }) }, ...mapMutations({ setDisc: 'SET_DISC' }) }, components: { Slider, Loading, Scroll } }</script>
设置轮播图组件:
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> <slot> </slot><!--插槽,外部我们引入slider,slider包裹的dom会被插入到这个部分。--> </div> <div class="dots"> <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots"></span> </div> </div></template><script type="text/ecmascript-6"> import {addClass} from 'common/js/dom' import BScroll from 'better-scroll' export default { name: 'slider', props: { loop: { type: Boolean, default: true }, autoPlay: { type: Boolean, default: true }, interval: { type: Number, default: 4000 } }, data() { return { dots: [], currentPageIndex: 0 } }, //初始化操作 mounted() { setTimeout(() => { this._setSliderWidth() this._initDots() this._initSlider() if (this.autoPlay) { this._play() } }, 20) window.addEventListener('resize', () => { if (!this.slider) { return } this._setSliderWidth(true) this.slider.refresh() }) }, activated() { if (this.autoPlay) { this._play() } }, deactivated() { clearTimeout(this.timer) }, beforeDestroy() { clearTimeout(this.timer) }, methods: { _setSliderWidth(isResize) { this.children = this.$refs.sliderGroup.children //通过此获得refs let width = 0 let sliderWidth = this.$refs.slider.clientWidth for (let i = 0; i < this.children.length; i++) { let child = this.children[i] addClass(child, 'slider-item') child.style.width = sliderWidth + 'px' width += sliderWidth } if (this.loop && !isResize) { width += 2 * sliderWidth } this.$refs.sliderGroup.style.width = width + 'px' }, _initSlider() { this.slider = new BScroll(this.$refs.slider, { scrollX: true, scrollY: false, momentum: false, snap: true, snapLoop: this.loop, snapThreshold: 0.3, snapSpeed: 400 }) this.slider.on('scrollEnd', () => { let pageIndex = this.slider.getCurrentPage().pageX if (this.loop) { pageIndex -= 1 } this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } }) this.slider.on('beforeScrollStart', () => { if (this.autoPlay) { clearTimeout(this.timer) } }) }, _initDots() { this.dots = new Array(this.children.length) }, _play() { let pageIndex = this.currentPageIndex + 1 if (this.loop) { pageIndex += 1 } this.timer = setTimeout(() => { this.slider.goToPage(pageIndex, 0, 400) }, this.interval) } } }</script>
recommend.vue
<template> <div class="recommend" ref="recommend"> <scroll ref="scroll" class="recommend-content" :data="discList"> <div> <div v-if="recommends.length" class="slider-wrapper" ref="sliderWrapper"> <slider> <!--遍历--> <div v-for="item in recommends" v-if="recommends.length>0"><!--当数据加载进来之后,在进行dom填充--> <a :href="item.linkUrl"> <img class="needsclick" @load="loadImage" :src="item.picUrl"> </a> </div> </slider> </div> <div class="recommend-list"> <h1 class="list-title">热门歌单推荐</h1> <ul> <li @click="selectItem(item)" v-for="item in discList" class="item"> <div class="icon"> <img width="60" height="60" v-lazy="item.imgurl"> </div> <div class="text"> <h2 class="name" v-html="item.creator.name"></h2> <p class="desc" v-html="item.dissname"></p> </div> </li> </ul> </div> </div> <div class="loading-container" v-show="!discList.length"> <loading></loading> </div> </scroll> <router-view></router-view> </div></template><script> export default{ data(){ return{ recommends:[] } }, created(){ this._getRecommend() }, methods:{ _getRecommend(){ //导入数据 this.recommends=res.data } }}</script>
4.歌单界面
后端代理在dev-server.js中
ar apiRoutes = express.Router()apiRoutes.get('/getDiscList', function (req, res) { var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg' axios.get(url, { headers: { referer: 'https://c.y.qq.com/', host: 'c.y.qq.com' }, params: req.query }).then((response) => { res.json(response.data) }).catch((e) => { console.log(e) })})
在这里用到了axios库,在浏览器发送https请求。
- 【WEB】vue2.0开发音乐播放器
- vue2.0网易云音乐播放器 (实时更新)
- WEB音乐播放器
- 音乐播放器开发
- 基于Vue2.0的音乐播放器(2)——歌手模块
- WEB音乐播放器源代码
- 基于Vue2.x开发的音乐播放器app(推荐界面+懒加载+axios获取后端接口实现)
- Android开发音乐播放器-音乐扫描
- Android开发音乐播放器
- Android开发音乐播放器
- 独立开发音乐播放器
- Android开发音乐播放器
- 音乐播放器开发记录
- 开发音乐播放器【1】
- iOS开发:音乐播放器
- 音乐播放器 - iOS开发
- 音乐播放器的开发
- 自己动手开发音乐播放器《十一》下载音乐播放器
- android 学习记录
- JS中的事件对象
- 二叉树的基本操作及一下问题(指针和终止输入)
- 作业2.2改错给x,y,z赋值
- 从网页搭建学习php开发——html入门学习笔记(一)
- 【WEB】vue2.0开发音乐播放器
- LeetCode 207. Course Schedule [Medium]
- Vue.js入门第三篇
- java压缩解压工具类
- A Mathematical Curiosity
- codeforces 889B. Restoration of string(拓扑排序)
- Rancher的管理员密码忘记怎么办?-登录RancherServer的mysql容器内,修改cattle库setting表中2个关于访问控制的字段的值
- pinpoint插件开发之二:从零开始新建一个插件
- 【AndroidStudio】手动配置gradle的方法