导语
近来看到不少运用vue制造的音乐播放器,挺好玩的,原本工作中也常常运用Vue,一同交流学习,好的话点个star哦
本项目特性以下 :
1. 原生js封装本身的跨域要求函数,支撑promise挪用,支撑错误处置惩罚 2. 制造一些复用性强的vue组件,如轮播图组件,支撑手势滑动,无穷轮回,图片按需加载 3. 清楚清楚明了的项目目次
项目堆栈地点
项目演示地点
从项目中提取的banner组件地点
一、计划目次
一个易于保护和迭代的项目,应该是具有牢靠的项目目次的,这里,在vue-cli天生的目次中,加入了services、directives、utils、store等目次,并在webpack中修正响应的导入地点:
1. services 用于全局治理接口和http要求
2. directives 用于增加全局指令
3. utils 用于安排通用js函数
4. store 用于治理vuex数据等
二、制造大众css,
重要采纳scss+em单元+currentColor继续父级色彩+before&after伪类制造
本项目制造的大众css有:
1. 播放器要用到的图标
2. 用于vue transition标签切换时运用的css3动画
3. css reset
4. 项目主题色彩,现在只能在项目初始化之前设置主题色彩,用于治理,一切组件主题色彩都来源于此
三、全局API
分红两个部份:
1. jsonp分装,担任http要求
2. 网络url地点,并放在API类上,并轮回将url用bind函数导入到jsonp封装函数中,其他要求一样可用
四、中心组件
包含 :
1. banner组件
2. 播放器
1.banner组件
该组件只对传入的数据举行处置惩罚,并响应转化,保证了组件的通用性
中心的函数重如果对***无穷轮回的处置惩罚、触摸屏滑动,图片按需加载***处置惩罚:
computed : {
sliderImg : function(){
const [...saveImg] = this.bannerlist, //拷贝图片列表数据,在展现地区的图片实际上首尾拷贝了一样的图片,即尾端拷贝第一张,首端拷贝末了一张
[imgfirst, ...other] = this.bannerlist;
saveImg.unshift(other[other.length-1])
saveImg.push(imgfirst)
return saveImg
},
},
mounted () {
if (this.bannerlist && this.bannerlist.length) {
this.interTimer = setInterval(()=>{
this.sliderStart()
},3000)
}
},
methods : {
linkURl (item) {
window.open(item[this.linkurl])
},
getURl (item,index) { //用于削减一次性要求,只加载当前的图片,加载以后增加标识
if (!item) {
return reloadImg
}
if (item.hasload) {
return item[this.picurl]
}
if (this.nowSlider == index-1) {
item.hasload = true
return item[this.picurl]
}
return reloadImg
},
stopSlider (e) {
e.preventDefault()
e.stopPropagation()
if (e.target != e.currentTarget) { //事宜托付节省下事宜绑定,消除当前绑定的dom
clearInterval(this.interTimer)
delete this.sliderActive['transition'] //封闭css3过渡结果
this.startTouch = e.targetTouches[0].screenX
}
},
moveSlider (e) {
e.preventDefault()
e.stopPropagation()
if (this.nowSlider === -1||this.nowSlider === this.bannerlist.length) { //首端与尾端未连接好制止滑动
return;
}
if (e.target != e.currentTarget) {
this.moveTouch = e.targetTouches[0].screenX
let slideDir = this.moveTouch - this.startTouch,
targetWidth = parseInt(window.getComputedStyle(e.target).width),
tranDir;
if (slideDir < -50 || slideDir > 50) { //加了50容错值,能防备触摸时图片倏忽闪烁
if (slideDir < 0) { //再从新补回差值
slideDir -= 50
} else {
slideDir += 50
}
tranDir = -targetWidth * (this.nowSlider+1) + slideDir//触摸时图片随手指挪动,间隔须减去当前图片宽度乘以当前转动索引
this.sliderActive.transform = `translate3d(${tranDir}px,0,0)`
}
}
},
continSilder (e) { //完毕触摸
e.preventDefault()
e.stopPropagation()
if (e.target != e.currentTarget && this.moveTouch) {
const slideDir = this.moveTouch - this.startTouch
if (slideDir < 0) {
this.nowSlider ++
} else if (slideDir > 0) {
this.nowSlider --
}
this.nowSlider --
this.sliderStart() //马上设置位置
this.moveTouch = 0 //清空手势位置
this.startTouch = 0
this.interTimer = setInterval(()=>{
this.sliderStart()
},3000)
}
},
sliderStart () {
this.nowSlider ++
this.nowSlider %= this.sliderImg.length
if (this.nowSlider === this.bannerlist.length) { //向右滑动到最大值时,将位置初始化并清0 nowSlider
setTimeout(() => { //设置一个定时器,用于异步处置惩罚,一个举行尾端拷贝的图片的一般滑动,这个处置惩罚在差不多抵达时重置,形成无穷轮回的错觉
this.sliderActive = {
transform: `translate3d(-100vw,0,0)`
}
this.nowSlider = 0
}, 500)
}
if (this.nowSlider === -1) { //向右滑动到最小值时,将位置置为最大值
setTimeout(() => {
this.nowSlider = this.bannerlist.length-1
this.sliderActive = {
transform: `translate3d(${-100*(this.nowSlider+1)}vw,0,0)`
}
}, 500)
}
this.sliderActive = Object.assign({},{
transition:'transform 0.5s',
transform: `translate3d(${-100*(this.nowSlider+1)}vw,0,0)`
})
}
}
2.播放器功用
播放器的一切功用重要依靠vuex(store.js)的掌握,因为音乐是在全部app内都播放的,故audio标签放在了App.vue中:
store.js:
APP.vue:
computed : {
audioSrc : function () { //对当前播放的音频切换,放在顶层
const song = this.$store.state.nowsong;
let audioTimer;
if (!song) {
this.$store.state.playing = false
clearInterval(audioTimer)
return null
}
this.$store.state.playing = true
audioTimer = setInterval(()=>{ //每秒猎取进度
let audio = document.getElementById('m-audio');
if (audio) {
this.$store.state.audioProgss = audio.currentTime/audio.duration*100+'%'
} else {
clearInterval(audioTimer)
}
},1000)
return `${API.url.getsong}${song.songid}.m4a?fromtag=46` //播放一首歌曲
},
playing : function () {
return this.$store.state.playing
},
},
directives : {
play : { //掌握是不是播放
update : function(el,binding) {
if (binding.value) {
el.play()
} else {
el.pause()
}
}
}
},