本系列文章是为了记录学习中的知识点,便于后期自己观看。如果有需要的同学请登录慕课网,找到Vue 2.0 高级实战-开发移动端音乐WebApp进行观看,传送门

完成后的页面状态以及项目结构如下:

一:创建轮播图组件slider.vue

1:在src/base下新建base文件夹,然后创建silder.vue:

<template>
<div class="slider" ref="slider">
<div class="slider-group" ref="sliderGroup">
<slot>
</slot>
</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 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> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable" .slider
min-height: 1px
.slider-group
position: relative
overflow: hidden
white-space: nowrap
.slider-item
float: left
box-sizing: border-box
overflow: hidden
text-align: center
a
display: block
width: 100%
overflow: hidden
text-decoration: none
img
display: block
width: 100%
.dots
position: absolute
right: 0
left: 0
bottom: 12px
text-align: center
font-size: 0
.dot
display: inline-block
margin: 0 4px
width: 8px
height: 8px
border-radius: 50%
background: $color-text-l
&.active
width: 20px
border-radius: 5px
background: $color-text-ll
</style>

  

2:组件中会含有addclass和hasclass的操作,但是这里没有用jquery,而是用原生的js封装了这两个方法。在src/common/js下新建dom.js:

export function hasClass(el, className) {
let reg = new RegExp('(^|\\s)' + className + '(\\s|$)')
return reg.test(el.className)
} export function addClass(el, className) {
if (hasClass(el, className)) {
return
} let newClass = el.className.split(' ')
newClass.push(className)
el.className = newClass.join(' ')
}

3:页面的数据是用jsonp跨域请求qq音乐上的数据。github地址:传送门。接下来我们在src/common/js下新建jsonp.js,用来封装公共的jsonp方法:

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) : ''
}

  

4:当我们异步请求数据的时候,一般都会有一些公共的参数,所以我们可以将这些公共的参数定义为常量。在src/api下新建config.js:

export const commonParams = {
g_tk: 1928093487,
inCharset: 'utf-8',
outCharset: 'utf-8',
notice: 0,
format: 'jsonp'
} export const options = {
param: 'jsonpCallback'
} export const ERR_OK = 0

4:定义获取轮播图数据的文件。在src/api下新建recommend.js:

import jsonp from 'common/js/jsonp'
import {commonParams, options} from './config' 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)
}

5:修改recommend.vue:

<template>
<div class="recommend" ref="recommend">
<div class="recommend-content">
<div v-if="recommends.length" class="slider-wrapper" ref="sliderWrapper">
<slider>
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img class="needsclick" @load="loadImage" :src="item.picUrl">
</a>
</div>
</slider>
</div>
</div>
</div>
</template> <script type="text/ecmascript-6">
import Slider from 'base/slider/slider'
import {getRecommend} from 'api/recommend'
import {ERR_OK} from 'api/config' export default {
data() {
return {
recommends: []
}
},
created() {
this._getRecommend()
},
methods: {
_getRecommend() {
getRecommend().then((res) => {
if (res.code === ERR_OK) {
this.recommends = res.data.slider
}
})
},
loadImage() {
if (!this.checkloaded) {
this.checkloaded = true
this.$refs.scroll.refresh()
}
}
},
components: {
Slider
}
}
</script> <style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable" .recommend
position: fixed
width: 100%
top: 88px
bottom: 0
.recommend-content
height: 100%
overflow: hidden
.slider-wrapper
position: relative
width: 100%
overflow: hidden
.recommend-list
.list-title
height: 65px
line-height: 65px
text-align: center
font-size: $font-size-medium
color: $color-theme
.item
display: flex
box-sizing: border-box
align-items: center
padding: 0 20px 20px 20px
.icon
flex: 0 0 60px
width: 60px
padding-right: 20px
.text
display: flex
flex-direction: column
justify-content: center
flex: 1
line-height: 20px
overflow: hidden
font-size: $font-size-medium
.name
margin-bottom: 10px
color: $color-text
.desc
color: $color-text-d
.loading-container
position: absolute
width: 100%
top: 50%
transform: translateY(-50%)
</style>

vue移动音乐app开发学习(三):轮播图组件的开发的更多相关文章

  1. 03 uni-app框架学习:轮播图组件的使用

    1.轮播图组件的使用 参照官方文档 2.在页面上加入这个组件 3.在页面中引去css样式 并编写样式 ps:upx单位是什么 简单来说 就相当于小程序中的rpx 是一个自适应的单位 会根据屏幕宽度自动 ...

  2. Vue实现音乐播放器(七):轮播图组件(二)

    轮播图组件 <template> <div class="slider" ref="slider"> <div class=&qu ...

  3. 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)

    大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...

  4. 用vue写一个仿简书的轮播图

    原文地址:用vue写一个仿简书的轮播图 先展示最终效果: Vue的理念是以数据驱动视图,所以拒绝通过改变元素的margin-top来实现滚动效果.写好css样式,只需改变每张图片的class即可实现轮 ...

  5. vue自定义轮播图组件 swiper

    1.banner 组件 components/Banner.vue <!-- 轮播图 组件 --> <template> <div class="swiper- ...

  6. vue项目一个页面使用多个轮播图详解

    1.html代码: <div v-for="(item,index) in arrDataList.Floor"> // 根据后台数据循环渲染多个轮播图组件 <d ...

  7. 原生JS面向对象思想封装轮播图组件

    原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能 ...

  8. Vue2 轮播图组件 slide组件

    Vue2原生始轮播图组件,支持宽度自适应.高度设置.轮播时间设置.左右箭头按钮控制,圆点按钮切换,以及箭头.圆点按钮是否显示. <v-carousel :slideData="slid ...

  9. 使用原生js将轮播图组件化

    代码地址如下:http://www.demodashi.com/demo/11316.html   这是一个轮播图组件,这里是代码地址,需要传入容器的id和图片地址,支持Internet Explor ...

随机推荐

  1. JavaScript字符串的处理方法

    1.字符方法charAt()和charCodeAt();这两个方法都接收一个参数 var stringValue = "hello world"; stringValue.char ...

  2. [MYSQL][1]创建,修改,删除表

    查看有哪些数据库: SHOW DATABASES; 创建,删除数据库: CREATE DATAABASE mydb; DROP DATABASE mydb; 查看有哪些表: SHOW TABLES; ...

  3. mysql 支持四字节设置

    设置文件mysql/bin/my.ini[mac用户在ect文件夹里创建文件my.cnf] 添加以下代码: [mysqld] character-set-server=utf8mb4

  4. Java并发之synchronized使用

    synchronized,是Java语言的关键字,读['siŋkrənaizd],当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.Java为何要使用sy ...

  5. SQL注入的浅尝辄止

    简单的说,SQL注入就是通过在前端页面输入SQL语句,导致系统暴露异常信息在前端页面显示,非法者通过这些异常信息获取数据库的相干信息,为攻击系统做准备.

  6. ChipScope Pro Inserter - "ERROR:NgdBuild:924 - bidirect pad net '<oDRAM0_A>' is driving non-buffer primitives

    解决方案: Using a IOBUF signal as a trigger for the ILA Inserter flow will cause a NGDBuild error. These ...

  7. 北京Uber优步司机奖励政策(2月1日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  8. Tomcat7后台通过get接收数据处理乱码

    Tomcat7后台通过get接收数据处理乱码 //因为tomcat7 默认将用get传来的数据用ISO-8859-1封装, //将ajax传过来的值解码,再转码,//因为tomcat7 默认将用get ...

  9. hdu1181变形课(floyd)

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  10. hdu1058Humble Numbers(动态规划)

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...