完成我的音乐页面
This commit is contained in:
parent
4724c209e8
commit
c2d105a0f2
@ -24,9 +24,9 @@
|
|||||||
-- 粉丝|0
|
-- 粉丝|0
|
||||||
-- 编辑资料|☑
|
-- 编辑资料|☑
|
||||||
-- 添加朋友|☑
|
-- 添加朋友|☑
|
||||||
-- 我的音乐|50%
|
-- 我的音乐|☑
|
||||||
-- 收藏视频\音乐|50%
|
|
||||||
-- 抖音商城|0
|
-- 抖音商城|0
|
||||||
|
-- 收藏视频\音乐|50%
|
||||||
-- 右侧菜单子页面|10%
|
-- 右侧菜单子页面|10%
|
||||||
-- 设置|☑
|
-- 设置|☑
|
||||||
-- -- 子页面|☑
|
-- -- 子页面|☑
|
||||||
|
|||||||
27
src/App.vue
27
src/App.vue
@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition name="fade">
|
|
||||||
<Mask v-if="maskDialog" @click="hideMaskDialog" :mode="maskDialogMode"></Mask>
|
|
||||||
</transition>
|
|
||||||
<transition :name="transitionName">
|
<transition :name="transitionName">
|
||||||
<!-- <keep-alive>-->
|
<!-- <keep-alive>-->
|
||||||
<!-- </keep-alive>-->
|
<!-- </keep-alive>-->
|
||||||
@ -19,26 +16,22 @@
|
|||||||
* try {navigator.control.gesture(false);} catch (e) {} //UC浏览器关闭默认手势事件
|
* try {navigator.control.gesture(false);} catch (e) {} //UC浏览器关闭默认手势事件
|
||||||
try {navigator.control.longpressMenu(false);} catch (e) {} //关闭长按弹出菜单
|
try {navigator.control.longpressMenu(false);} catch (e) {} //关闭长按弹出菜单
|
||||||
* */
|
* */
|
||||||
|
import * as Vue from "vue";
|
||||||
|
import Loading from "./components/Loading";
|
||||||
|
import Mask from "./components/Mask";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
Mask
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
transitionName: 'go',
|
transitionName: 'go',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {},
|
||||||
maskDialog() {
|
methods: {},
|
||||||
return this.$store.state.maskDialog
|
|
||||||
},
|
|
||||||
maskDialogMode() {
|
|
||||||
return this.$store.state.maskDialogMode
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
hideMaskDialog() {
|
|
||||||
this.$store.commit('setMaskDialog', {state: false, mode: this.maskDialogMode})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// watch $route 决定使用哪种过渡
|
// watch $route 决定使用哪种过渡
|
||||||
watch: {
|
watch: {
|
||||||
'$route'(to, from) {
|
'$route'(to, from) {
|
||||||
@ -107,7 +100,7 @@ export default {
|
|||||||
const toDepth = routeDeep.indexOf(to.path)
|
const toDepth = routeDeep.indexOf(to.path)
|
||||||
const fromDepth = routeDeep.indexOf(from.path)
|
const fromDepth = routeDeep.indexOf(from.path)
|
||||||
this.transitionName = toDepth > fromDepth ? 'go' : 'back'
|
this.transitionName = toDepth > fromDepth ? 'go' : 'back'
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.$store.dispatch('getFriends')
|
// this.$store.dispatch('getFriends')
|
||||||
|
|||||||
BIN
src/assets/img/icon/me/float-play.png
Normal file
BIN
src/assets/img/icon/me/float-play.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="home-index"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
@cancel="cancel"
|
@cancel="cancel"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
></div>
|
></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
//未以组件的方式使用,FromBottomDialog.vue里面是用js append到dom里面去的,
|
||||||
|
//以组件的方式使用,不好随意插位置,插到app下面,又会出现定位覆盖的问题
|
||||||
export default {
|
export default {
|
||||||
name: "Mask",
|
name: "Mask",
|
||||||
props: {
|
props: {
|
||||||
@ -15,7 +17,7 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style lang="less">
|
||||||
|
|
||||||
.Mask {
|
.Mask {
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
@ -35,7 +37,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.lightgray {
|
&.lightgray {
|
||||||
background: rgba(0, 0, 0, 0.15);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.white {
|
&.white {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
:page-id="pageId"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
@cancel="closeShare"
|
@cancel="closeShare"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
@ -24,34 +25,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<div class="shares ">
|
<div class="shares">
|
||||||
<template v-if="mode === 'video'">
|
<template v-if="mode === 'video'">
|
||||||
<div class="share-to" @click="$no">
|
<div class="share-to" @click="$no">
|
||||||
<img src="../assets/img/icon/components/video/torichang.png" alt="">
|
<img src="../assets/img/icon/components/video/torichang.png" alt="">
|
||||||
<span>分享日常</span>
|
<span>分享日常</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
|
||||||
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
|
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
|
||||||
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
|
<span>私信朋友</span>
|
||||||
<span>私信朋友</span>
|
</div>
|
||||||
</div>
|
<div class="share-to" @click="closeShare($emit('showShare2WeChatZone'))">
|
||||||
<div class="share-to" @click="closeShare($emit('showShare2WeChatZone'))">
|
<img src="../assets/img/icon/components/video/towechat.webp" alt="">
|
||||||
<img src="../assets/img/icon/components/video/towechat.webp" alt="">
|
<span>朋友圈</span>
|
||||||
<span>朋友圈</span>
|
</div>
|
||||||
</div>
|
<div class="share-to" @click="closeShare($emit('share2WeChat'))">
|
||||||
<div class="share-to" @click="closeShare($emit('share2WeChat'))">
|
<img src="../assets/img/icon/components/video/towechatchat.webp" alt="">
|
||||||
<img src="../assets/img/icon/components/video/towechatchat.webp" alt="">
|
<span>微信好友</span>
|
||||||
<span>微信好友</span>
|
</div>
|
||||||
</div>
|
<div class="share-to" @click="closeShare($emit('share2QQZone'))">
|
||||||
<div class="share-to" @click="closeShare($emit('share2QQZone'))">
|
<img src="../assets/img/icon/components/video/tozone.webp" alt="">
|
||||||
<img src="../assets/img/icon/components/video/tozone.webp" alt="">
|
<span>QQ空间</span>
|
||||||
<span>QQ空间</span>
|
</div>
|
||||||
</div>
|
<div class="share-to" @click="closeShare($emit('share2QQ'))">
|
||||||
<div class="share-to" @click="closeShare($emit('share2QQ'))">
|
<img src="../assets/img/icon/components/video/toqq.webp" alt="">
|
||||||
<img src="../assets/img/icon/components/video/toqq.webp" alt="">
|
<span>QQ好友</span>
|
||||||
<span>QQ好友</span>
|
</div>
|
||||||
</div>
|
|
||||||
<template v-if="mode === 'video'">
|
|
||||||
<div class="share-to" @click="closeShare($emit('showShareDuoshan'))">
|
<div class="share-to" @click="closeShare($emit('showShareDuoshan'))">
|
||||||
<img src="../assets/img/icon/components/video/duoshan.png" alt="">
|
<img src="../assets/img/icon/components/video/duoshan.png" alt="">
|
||||||
<span>多闪</span>
|
<span>多闪</span>
|
||||||
@ -60,11 +59,47 @@
|
|||||||
<img src="../assets/img/icon/components/video/totoutiao.webp" alt="">
|
<img src="../assets/img/icon/components/video/totoutiao.webp" alt="">
|
||||||
<span>今日头条</span>
|
<span>今日头条</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('share2Webo'))">
|
||||||
|
<img src="../assets/img/icon/components/video/toweibo.webp" alt="">
|
||||||
|
<span>微博</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="mode === 'music'">
|
||||||
|
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
|
||||||
|
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
|
||||||
|
<span>私信朋友</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('showShare2WeChatZone'))">
|
||||||
|
<img src="../assets/img/icon/components/video/towechat.webp" alt="">
|
||||||
|
<span>朋友圈</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('share2WeChat'))">
|
||||||
|
<img src="../assets/img/icon/components/video/towechatchat.webp" alt="">
|
||||||
|
<span>微信好友</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('share2QQZone'))">
|
||||||
|
<img src="../assets/img/icon/components/video/tozone.webp" alt="">
|
||||||
|
<span>QQ空间</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('share2QQ'))">
|
||||||
|
<img src="../assets/img/icon/components/video/toqq.webp" alt="">
|
||||||
|
<span>QQ好友</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('share2Webo'))">
|
||||||
|
<img src="../assets/img/icon/components/video/toweibo.webp" alt="">
|
||||||
|
<span>微博</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="mode === 'my-music'">
|
||||||
|
<div class="share-to" @click="$no">
|
||||||
|
<img src="../assets/img/icon/components/video/torichang.png" alt="">
|
||||||
|
<span>转发到日常</span>
|
||||||
|
</div>
|
||||||
|
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
|
||||||
|
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
|
||||||
|
<span>私信朋友</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="share-to" @click="closeShare($emit('share2Webo'))">
|
|
||||||
<img src="../assets/img/icon/components/video/toweibo.webp" alt="">
|
|
||||||
<span>微博</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="toolbar ">
|
<div class="toolbar ">
|
||||||
<template v-if="mode === 'qrcode'">
|
<template v-if="mode === 'qrcode'">
|
||||||
@ -174,6 +209,10 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
pageId: {
|
||||||
|
type: String,
|
||||||
|
default: 'home-index'
|
||||||
|
},
|
||||||
canDownload: {
|
canDownload: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
|||||||
@ -42,11 +42,6 @@ export default {
|
|||||||
// default: 'light'
|
// default: 'light'
|
||||||
// default: 'white'
|
// default: 'white'
|
||||||
},
|
},
|
||||||
//触摸,是否可以滑动
|
|
||||||
touchMoved: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
maskMode: {
|
maskMode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'dark'
|
default: 'dark'
|
||||||
@ -61,41 +56,40 @@ export default {
|
|||||||
},
|
},
|
||||||
pageId: {
|
pageId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null,
|
||||||
}
|
required: true
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
type: String,
|
||||||
|
default: '.5rem .5rem 0 0'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
modelValue(newVal) {
|
modelValue(newVal) {
|
||||||
let app = document.getElementById('app')
|
let page = document.getElementById(this.pageId)
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
if (this.pageId) {
|
this.pagePosition = this.$getCss2(page, 'position')
|
||||||
let page = document.getElementById(this.pageId)
|
page.style.position = 'absolute'
|
||||||
this.pagePosition = this.$getCss2(page, 'position')
|
|
||||||
page.style.position = 'absolute'
|
|
||||||
} else {
|
|
||||||
this.pagePosition = this.$getCss2(app.children[0], 'position')
|
|
||||||
app.children[0].style.position = 'absolute'
|
|
||||||
}
|
|
||||||
this.scroll = document.documentElement.scrollTop
|
this.scroll = document.documentElement.scrollTop
|
||||||
document.body.style.position = 'fixed'
|
document.body.style.position = 'fixed'
|
||||||
document.body.style.top = -this.scroll + 'px'
|
document.body.style.top = -this.scroll + 'px'
|
||||||
|
|
||||||
|
let maskTemplate = `<div class="Mask fade-in ${this.maskMode}"></div>`
|
||||||
|
let mask = new Dom().create(maskTemplate)
|
||||||
|
mask.on('click', () => this.hide(false))
|
||||||
|
page.appendChild(mask.els[0])
|
||||||
} else {
|
} else {
|
||||||
if (this.pageId) {
|
let page = document.getElementById(this.pageId)
|
||||||
let page = document.getElementById(this.pageId)
|
page.style.position = this.pagePosition || 'fixed'
|
||||||
page.style.position = this.pagePosition || 'fixed'
|
|
||||||
} else {
|
|
||||||
app.children[1].style.position = this.pagePosition || 'fixed'
|
|
||||||
}
|
|
||||||
document.body.style.position = 'static'
|
document.body.style.position = 'static'
|
||||||
document.documentElement.scrollTop = this.scroll
|
document.documentElement.scrollTop = this.scroll
|
||||||
|
|
||||||
|
let mask = new Dom('.Mask').replaceClass('fade-in', 'fade-out')
|
||||||
|
setTimeout(() => {
|
||||||
|
mask.remove()
|
||||||
|
}, 300)
|
||||||
}
|
}
|
||||||
this.$store.commit('setMaskDialog', {state: newVal, mode: this.maskMode})
|
|
||||||
},
|
},
|
||||||
maskDialog(newVal) {
|
|
||||||
if (!newVal) {
|
|
||||||
this.hide(newVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -106,11 +100,7 @@ export default {
|
|||||||
pagePosition: null
|
pagePosition: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {},
|
||||||
maskDialog() {
|
|
||||||
return this.$store.state.maskDialog
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
created() {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -149,13 +139,11 @@ export default {
|
|||||||
this.$emit('cancel')
|
this.$emit('cancel')
|
||||||
},
|
},
|
||||||
start(e) {
|
start(e) {
|
||||||
if (!this.touchMoved) return;
|
|
||||||
if (this.$refs.dialog.scrollTop !== 0) return
|
if (this.$refs.dialog.scrollTop !== 0) return
|
||||||
this.startLocationY = e.touches[0].pageY
|
this.startLocationY = e.touches[0].pageY
|
||||||
this.startTime = Date.now()
|
this.startTime = Date.now()
|
||||||
},
|
},
|
||||||
move(e) {
|
move(e) {
|
||||||
if (!this.touchMoved) return;
|
|
||||||
if (this.$refs.dialog.scrollTop !== 0) return
|
if (this.$refs.dialog.scrollTop !== 0) return
|
||||||
this.moveYDistance = e.touches[0].pageY - this.startLocationY
|
this.moveYDistance = e.touches[0].pageY - this.startLocationY
|
||||||
if (this.moveYDistance > 0) {
|
if (this.moveYDistance > 0) {
|
||||||
@ -164,7 +152,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
end(e) {
|
end(e) {
|
||||||
if (!this.touchMoved) return;
|
|
||||||
|
|
||||||
//点击
|
//点击
|
||||||
if (Date.now() - this.startTime < 150 && Math.abs(this.moveYDistance) < 30) {
|
if (Date.now() - this.startTime < 150 && Math.abs(this.moveYDistance) < 30) {
|
||||||
@ -203,7 +190,7 @@ export default {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: .5rem .5rem 0 0;
|
border-radius: v-bind(borderRadius);
|
||||||
transition: all .3s;
|
transition: all .3s;
|
||||||
|
|
||||||
&.dark {
|
&.dark {
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import {nextTick} from "vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BaseSlideList",
|
name: "BaseSlideList",
|
||||||
props: {
|
props: {
|
||||||
@ -17,6 +19,15 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: () => 0
|
default: () => 0
|
||||||
},
|
},
|
||||||
|
//改变index,是否使用动画
|
||||||
|
changeActiveIndexUseAnim: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
canMove: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -42,8 +53,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
activeIndex() {
|
activeIndex(newVal) {
|
||||||
// console.log('activeIndex')
|
|
||||||
this.changeIndex()
|
this.changeIndex()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -52,14 +62,29 @@ export default {
|
|||||||
await this.checkChildren()
|
await this.checkChildren()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkChildren() {
|
async changeIndex() {
|
||||||
this.slideList = this.$refs.slideList
|
await this.checkChildren()
|
||||||
this.slideItems = this.slideList.children
|
this.currentSlideItemIndex = this.activeIndex
|
||||||
this.wrapperHeight = this.$getCss(this.slideList, 'height')
|
if (this.changeActiveIndexUseAnim) {
|
||||||
for (let i = 0; i < this.slideItems.length; i++) {
|
this.$setCss(this.slideList, 'transition-duration', `300ms`)
|
||||||
let el = this.slideItems[i]
|
|
||||||
this.slideItemsHeights.push(this.$getCss(el, 'height'))
|
|
||||||
}
|
}
|
||||||
|
this.$setCss(this.slideList, 'transform', `translate3d(0px, ${-this.getHeight(this.currentSlideItemIndex) + this.moveYDistance}px, 0px)`)
|
||||||
|
this.$attrs['onUpdate:active-index'] && this.$emit('update:active-index', this.currentSlideItemIndex)
|
||||||
|
},
|
||||||
|
checkChildren() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
nextTick(() => {
|
||||||
|
this.slideList = this.$refs.slideList
|
||||||
|
this.slideItems = this.slideList.children
|
||||||
|
this.wrapperHeight = this.$getCss(this.slideList, 'height')
|
||||||
|
this.slideItemsHeights = []
|
||||||
|
for (let i = 0; i < this.slideItems.length; i++) {
|
||||||
|
let el = this.slideItems[i]
|
||||||
|
this.slideItemsHeights.push(this.$getCss(el, 'height'))
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
touchStart(e) {
|
touchStart(e) {
|
||||||
this.checkChildren()
|
this.checkChildren()
|
||||||
@ -70,6 +95,7 @@ export default {
|
|||||||
this.startTime = Date.now()
|
this.startTime = Date.now()
|
||||||
},
|
},
|
||||||
touchMove(e) {
|
touchMove(e) {
|
||||||
|
if (!this.canMove) return;
|
||||||
this.moveXDistance = e.touches[0].pageX - this.startLocationX
|
this.moveXDistance = e.touches[0].pageX - this.startLocationX
|
||||||
this.moveYDistance = e.touches[0].pageY - this.startLocationY
|
this.moveYDistance = e.touches[0].pageY - this.startLocationY
|
||||||
|
|
||||||
@ -90,6 +116,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
touchEnd(e) {
|
touchEnd(e) {
|
||||||
|
if (!this.canMove) return;
|
||||||
if (this.isCanDownWiping) {
|
if (this.isCanDownWiping) {
|
||||||
if (this.currentSlideItemIndex === 0 && !this.isDrawDown) return
|
if (this.currentSlideItemIndex === 0 && !this.isDrawDown) return
|
||||||
if (this.currentSlideItemIndex === this.slideItems.length - 1 && this.isDrawDown) return this.$attrs['onEnd'] && this.$emit('end')
|
if (this.currentSlideItemIndex === this.slideItems.length - 1 && this.isDrawDown) return this.$attrs['onEnd'] && this.$emit('end')
|
||||||
|
|||||||
@ -60,6 +60,7 @@
|
|||||||
<Share v-model="isSharing"
|
<Share v-model="isSharing"
|
||||||
mode="music"
|
mode="music"
|
||||||
ref="share"
|
ref="share"
|
||||||
|
pageId="Music"
|
||||||
@showDouyinCode="showDouyinCode = true"
|
@showDouyinCode="showDouyinCode = true"
|
||||||
@showShare2WeChatZone="shareType = 2"
|
@showShare2WeChatZone="shareType = 2"
|
||||||
@share2WeChat="shareType = 3"
|
@share2WeChat="shareType = 3"
|
||||||
@ -85,7 +86,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
<ShareToFriend v-model="shareToFriend"/>
|
<ShareToFriend pageId="Music" v-model="shareToFriend"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="home-index"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
maskMode="dark"
|
maskMode="dark"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="home-index"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
maskMode="dark"
|
maskMode="dark"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
:page-id="pageId"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
@cancel="cancel"
|
@cancel="cancel"
|
||||||
maskMode="light"
|
maskMode="light"
|
||||||
@ -108,7 +109,11 @@ export default {
|
|||||||
Check
|
Check
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: false
|
modelValue: false,
|
||||||
|
pageId: {
|
||||||
|
type: String,
|
||||||
|
default: 'home-index'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -167,7 +172,7 @@ export default {
|
|||||||
|
|
||||||
.button {
|
.button {
|
||||||
width: 6.4rem;
|
width: 6.4rem;
|
||||||
height: 2.6rem!important;
|
height: 2.6rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@avatar-width: 3.8rem;
|
@avatar-width: 3.8rem;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="other-login">
|
<div class="other-login" id="other-login">
|
||||||
<BaseHeader mode="light" backMode="dark" backImg="back">
|
<BaseHeader mode="light" backMode="dark" backImg="back">
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f16">帮助</span>
|
<span class="f16">帮助</span>
|
||||||
@ -41,6 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="other-login"
|
||||||
v-model="isOtherLogin"
|
v-model="isOtherLogin"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
height="27rem"
|
height="27rem"
|
||||||
|
|||||||
@ -9,13 +9,9 @@
|
|||||||
</IndicatorLight>
|
</IndicatorLight>
|
||||||
<back style="opacity: 0;" mode="light" img="back"/>
|
<back style="opacity: 0;" mode="light" img="back"/>
|
||||||
</div>
|
</div>
|
||||||
<SlideRowList
|
<SlideRowList name="myMusicList" v-model:active-index="slideIndex">
|
||||||
name="myMusicList"
|
|
||||||
v-model:active-index="slideIndex">
|
|
||||||
<SlideItem>
|
<SlideItem>
|
||||||
<SlideColumnList>
|
<GuessMusic :list="guessMusic"/>
|
||||||
<SlideItemMusic v-model="guessMusic[index]" v-for="(item,index) in guessMusic "/>
|
|
||||||
</SlideColumnList>
|
|
||||||
</SlideItem>
|
</SlideItem>
|
||||||
<SlideItem style="overflow: auto;">
|
<SlideItem style="overflow: auto;">
|
||||||
<div class="my-collect">
|
<div class="my-collect">
|
||||||
@ -29,7 +25,7 @@
|
|||||||
<img class="menu" src="../../assets/img/icon/menu-white.png" alt="">
|
<img class="menu" src="../../assets/img/icon/menu-white.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="collect-list">
|
<div class="collect-list">
|
||||||
<div class="item" v-for="item in collectMusic" @click="playMusic(item)">
|
<div class="item" v-for="(item,index) in collectMusic" @click="page2PlayMusic(item)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
|
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
|
||||||
@ -44,7 +40,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img v-if="item.is_play" class="playing-icon" src="../../assets/img/icon/me/pinlv.gif">
|
<img v-if="page2SlideIndex === index" class="playing-icon"
|
||||||
|
src="../../assets/img/icon/me/pinlv.gif">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -56,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="recommend-list">
|
<div class="recommend-list">
|
||||||
<div class="item" v-for="item in recommendMusic" @click="playMusic(item)">
|
<div class="item" v-for="(item,index) in recommendMusic" @click="page2PlayMusic(item)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
|
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
|
||||||
@ -71,39 +68,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img v-if="item.is_play" class="playing-icon" src="../../assets/img/icon/me/pinlv.gif">
|
<img v-if="page2SlideIndex - collectMusic.length === index" class="playing-icon"
|
||||||
|
src="../../assets/img/icon/me/pinlv.gif">
|
||||||
<div class="collect-icon">
|
<div class="collect-icon">
|
||||||
<img src="../../assets/img/icon/star-white.png" v-show="!isCollect" @click="isCollect = !isCollect">
|
<img src="../../assets/img/icon/star-white.png" v-show="!item.isCollect"
|
||||||
<img src="../../assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect">
|
@click.stop="item.isCollect = !item.isCollect">
|
||||||
|
<img src="../../assets/img/icon/star-yellow.png" v-show="item.isCollect"
|
||||||
|
@click.stop="item.isCollect = !item.isCollect">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="playing" @click="isShowCollectDialog = true">
|
<transition name="float-play">
|
||||||
<div class="playing-wrapper">
|
<div v-if="isShowFloatPlay" class="playing" @click="isShowCollectDialog = true">
|
||||||
<div class="cover-wrapper">
|
<div class="playing-wrapper">
|
||||||
<img v-lazy="$imgPreview(currentMusic.cover)" alt="" class="cover">
|
<div class="cover-wrapper">
|
||||||
|
<img v-lazy="$imgPreview(currentMusic.cover)" alt="" class="cover">
|
||||||
|
</div>
|
||||||
|
<div class="name">{{ currentMusic.name }}</div>
|
||||||
|
<img v-show="page2IsPlay" @click.stop="togglePage2Play" class="option"
|
||||||
|
src="../../assets/img/icon/me/float-pause-one.png" alt="">
|
||||||
|
<img v-show="!page2IsPlay" @click.stop="togglePage2Play" class="option"
|
||||||
|
src="../../assets/img/icon/me/float-play.png" alt="">
|
||||||
|
<img @click.stop="$no" class="menu-list" src="../../assets/img/icon/me/music-list.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="name">{{ currentMusic.name }}</div>
|
|
||||||
<img class="option" src="../../assets/img/icon/me/float-pause-one.png" alt="">
|
|
||||||
<img class="menu-list" src="../../assets/img/icon/me/music-list.png" alt="">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</SlideItem>
|
</SlideItem>
|
||||||
</SlideRowList>
|
</SlideRowList>
|
||||||
|
|
||||||
|
|
||||||
<transition name="my-collect-dialog">
|
<transition name="my-collect-dialog">
|
||||||
<div class="my-collect-dialog" v-if="isShowCollectDialog">
|
<div class="my-collect-dialog" v-show="isShowCollectDialog">
|
||||||
<div class="dialog-header">
|
<div class="dialog-header">
|
||||||
<back class="close" mode="light" img="back" @click="isShowCollectDialog = false"/>
|
<back class="close" mode="light" img="back" @click="isShowCollectDialog = false"/>
|
||||||
<span>我的收藏</span>
|
<span>我的收藏</span>
|
||||||
<back style="opacity: 0;" mode="light" img="back"/>
|
<back style="opacity: 0;" mode="light" img="back"/>
|
||||||
</div>
|
</div>
|
||||||
<SlideColumnList>
|
<CollectMusic ref="CollectMusic" :list="page2Music" v-model:page2SlideIndex="page2SlideIndex"/>
|
||||||
<SlideItemMusic v-model="guessMusic[index]" v-for="(item,index) in guessMusic "/>
|
|
||||||
</SlideColumnList>
|
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@ -116,17 +120,24 @@ import gaobaiqiqiu from '../../assets/data/lyrics/gaobaiqiqiu.lrc'
|
|||||||
import Switches from "../message/components/swtich/switches";
|
import Switches from "../message/components/swtich/switches";
|
||||||
import SlideItemMusic from "./components/SlideItemMusic";
|
import SlideItemMusic from "./components/SlideItemMusic";
|
||||||
import IndicatorLight from "../../components/slide/IndicatorLight";
|
import IndicatorLight from "../../components/slide/IndicatorLight";
|
||||||
|
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
|
||||||
|
import GuessMusic from "./components/GuessMusic";
|
||||||
|
import CollectMusic from "./components/CollectMusic";
|
||||||
|
|
||||||
|
//TODO 两个page页面的播放冲突未做
|
||||||
export default {
|
export default {
|
||||||
name: "MyMusic",
|
name: "MyMusic",
|
||||||
components: {
|
components: {
|
||||||
|
FromBottomDialog,
|
||||||
Switches,
|
Switches,
|
||||||
SlideItemMusic,
|
SlideItemMusic,
|
||||||
IndicatorLight
|
IndicatorLight,
|
||||||
|
GuessMusic,
|
||||||
|
CollectMusic
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
slideIndex: 0,
|
slideIndex: 1,
|
||||||
currentMusic: {
|
currentMusic: {
|
||||||
name: '告白气球',
|
name: '告白气球',
|
||||||
mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3',
|
mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3',
|
||||||
@ -140,99 +151,43 @@ export default {
|
|||||||
collectMusic: [],
|
collectMusic: [],
|
||||||
recommendMusic: [],
|
recommendMusic: [],
|
||||||
guessMusic: [],
|
guessMusic: [],
|
||||||
lyricsTexts: [],
|
|
||||||
lyricsFullTexts: [],
|
|
||||||
isShowCollectDialog: false,
|
isShowCollectDialog: false,
|
||||||
isPlay: false,
|
isShowFloatPlay: false,
|
||||||
|
|
||||||
isAutoPlay: true,
|
isAutoPlay: true,
|
||||||
isLoop: false,
|
|
||||||
isMove: false,
|
|
||||||
isCollect: false,
|
isCollect: false,
|
||||||
isFullLyrics: false,
|
|
||||||
lastPageX: 0,
|
page2SlideIndex: -1,
|
||||||
pageX: 0,
|
page2IsPlay: false
|
||||||
audio: new Audio(),
|
|
||||||
duration: 0,
|
|
||||||
currentTime: 0,
|
|
||||||
step: 0,
|
|
||||||
startX: 0,
|
|
||||||
slideBarWidth: 0
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['bodyWidth'])
|
...mapState(['bodyWidth']),
|
||||||
|
page2Music() {
|
||||||
|
return this.collectMusic.concat(this.recommendMusic)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getCollectMusic()
|
this.getCollectMusic()
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
this.audio.volume = .2
|
|
||||||
}
|
|
||||||
this.audio.addEventListener('loadedmetadata', e => {
|
|
||||||
this.duration = this.audio.duration
|
|
||||||
this.slideBarWidth = this.$refs.slideBar.clientWidth
|
|
||||||
this.step = this.slideBarWidth / Math.floor(this.duration)
|
|
||||||
})
|
|
||||||
let lrcObj = this.createLrcObj(gaobaiqiqiu);
|
|
||||||
this.lyricsTexts.push(lrcObj.ms[0])
|
|
||||||
this.lyricsTexts.push(lrcObj.ms[1])
|
|
||||||
lrcObj.ms.map(v => {
|
|
||||||
if (v.c) this.lyricsFullTexts.push(v)
|
|
||||||
})
|
|
||||||
console.log(lrcObj.ms)
|
|
||||||
this.audio.addEventListener('timeupdate', e => {
|
|
||||||
let currentTime = Math.ceil(e.target.currentTime)
|
|
||||||
// let lastLyricsText = this.lyricsTexts[this.lyricsTexts.length - 1]
|
|
||||||
// if (Number(lastLyricsText.t) < currentTime) {
|
|
||||||
// for (let i = 0; i < lrcObj.ms.length; i++) {
|
|
||||||
// let item = lrcObj.ms[i]
|
|
||||||
// if (Number(item.t) > currentTime) {
|
|
||||||
// if (item.c) {
|
|
||||||
// console.log(item)
|
|
||||||
// this.t(item)
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (!this.isMove) {
|
|
||||||
this.currentTime = currentTime
|
|
||||||
if (Math.ceil(e.target.currentTime) * this.step > this.slideBarWidth - 5) {
|
|
||||||
this.pageX = this.slideBarWidth - 5
|
|
||||||
} else {
|
|
||||||
this.pageX = Math.ceil(e.target.currentTime) * this.step
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.audio.addEventListener('play', e => this.isPlay = true)
|
|
||||||
this.audio.addEventListener('ended', e => {
|
|
||||||
if (this.isLoop) {
|
|
||||||
this.lastPageX = 0
|
|
||||||
this.audio.currentTime = 0
|
|
||||||
this.audio.play()
|
|
||||||
} else {
|
|
||||||
this.isPlay = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
playMusic(item) {
|
togglePage2Play() {
|
||||||
this.collectMusic.map(v => v.is_play = false)
|
this.page2IsPlay = !this.page2IsPlay
|
||||||
this.recommendMusic.map(v => v.is_play = false)
|
if (this.page2IsPlay) {
|
||||||
item.is_play = true
|
this.$refs.CollectMusic.play(this.page2SlideIndex)
|
||||||
this.currentMusic = item
|
|
||||||
this.audio.src = this.currentMusic.mp3
|
|
||||||
this.togglePlay(true)
|
|
||||||
},
|
|
||||||
togglePlay(state) {
|
|
||||||
this.currentMusic.is_play = state || !this.currentMusic.is_play
|
|
||||||
if (this.currentMusic.is_play) {
|
|
||||||
this.audio.play()
|
|
||||||
} else {
|
} else {
|
||||||
this.audio.pause()
|
this.$refs.CollectMusic.pause()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
page2PlayMusic(item) {
|
||||||
|
this.currentMusic = item
|
||||||
|
this.isShowFloatPlay = true
|
||||||
|
this.page2IsPlay = true
|
||||||
|
this.page2SlideIndex = this.page2Music.findIndex(v => v.name === item.name)
|
||||||
|
this.isShowCollectDialog = true
|
||||||
|
this.$refs.CollectMusic.play(this.page2SlideIndex)
|
||||||
|
},
|
||||||
async getCollectMusic() {
|
async getCollectMusic() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
let res = await this.$api.videos.collect()
|
let res = await this.$api.videos.collect()
|
||||||
@ -242,93 +197,6 @@ export default {
|
|||||||
this.guessMusic = this.recommendMusic = res.data.music.list.slice(2, -1)
|
this.guessMusic = this.recommendMusic = res.data.music.list.slice(2, -1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createLrcObj(lrc) {
|
|
||||||
let oLRC = {
|
|
||||||
ti: "", //歌曲名
|
|
||||||
ar: "", //演唱者
|
|
||||||
al: "", //专辑名
|
|
||||||
by: "", //歌词制作人
|
|
||||||
offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置
|
|
||||||
ms: [] //歌词数组{t:时间,c:歌词}
|
|
||||||
};
|
|
||||||
if (lrc.length === 0) return;
|
|
||||||
let lrcs = lrc.split('\n');//用回车拆分成数组
|
|
||||||
for (let i in lrcs) {//遍历歌词数组
|
|
||||||
lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, ""); //去除前后空格
|
|
||||||
let t = lrcs[i].substring(lrcs[i].indexOf("[") + 1, lrcs[i].indexOf("]"));//取[]间的内容
|
|
||||||
let s = t.split(":");//分离:前后文字
|
|
||||||
if (isNaN(parseInt(s[0]))) { //不是数值
|
|
||||||
for (let i in oLRC) {
|
|
||||||
if (i != "ms" && i == s[0].toLowerCase()) {
|
|
||||||
oLRC[i] = s[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { //是数值
|
|
||||||
let arr = lrcs[i].match(/\[(\d+:.+?)\]/g);//提取时间字段,可能有多个
|
|
||||||
let start = 0;
|
|
||||||
for (let k in arr) {
|
|
||||||
start += arr[k].length; //计算歌词位置
|
|
||||||
}
|
|
||||||
let content = lrcs[i].substring(start);//获取歌词内容
|
|
||||||
for (let k in arr) {
|
|
||||||
let t = arr[k].substring(1, arr[k].length - 1);//取[]间的内容
|
|
||||||
let s = t.split(":");//分离:前后文字
|
|
||||||
oLRC.ms.push({//对象{t:时间,c:歌词}加入ms数组
|
|
||||||
t: (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(3),
|
|
||||||
c: content
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oLRC.ms.sort(function (a, b) {//按时间顺序排序
|
|
||||||
return a.t - b.t;
|
|
||||||
});
|
|
||||||
return oLRC
|
|
||||||
/*
|
|
||||||
for(let i in oLRC){ //查看解析结果
|
|
||||||
console.log(i,":",oLRC[i]);
|
|
||||||
}*/
|
|
||||||
},
|
|
||||||
t(txt) {
|
|
||||||
// if (this.test.length === 2) return
|
|
||||||
this.lyricsTexts.push(txt)
|
|
||||||
nextTick(() => {
|
|
||||||
let comments = this.$refs['lyrics-wrapper']
|
|
||||||
comments.scrollTo({top: comments.scrollHeight - comments.clientHeight, behavior: 'smooth'})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
start(e) {
|
|
||||||
this.startX = e.touches[0].pageX
|
|
||||||
},
|
|
||||||
move(e) {
|
|
||||||
this.isMove = true
|
|
||||||
this.pageX = this.lastPageX + (e.touches[0].pageX - this.startX)
|
|
||||||
if (this.pageX < 0) this.pageX = 0
|
|
||||||
if (this.pageX > this.slideBarWidth) this.pageX = this.slideBarWidth - 5
|
|
||||||
this.currentTime = Math.ceil(this.pageX / this.step)
|
|
||||||
globalMethods.$stopPropagation(e)
|
|
||||||
},
|
|
||||||
end(e) {
|
|
||||||
this.lastPageX = this.pageX
|
|
||||||
this.currentTime = Math.ceil(this.pageX / this.step)
|
|
||||||
this.audio.currentTime = this.currentTime
|
|
||||||
this.audio.play()
|
|
||||||
this.isMove = false
|
|
||||||
globalMethods.$stopPropagation(e)
|
|
||||||
},
|
|
||||||
$durationTime(time) {
|
|
||||||
if (time === 0) return '00:00'
|
|
||||||
else {
|
|
||||||
return this.$duration(time)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
durationStyle(type) {
|
|
||||||
// return {}
|
|
||||||
if (type === 1) {
|
|
||||||
return {width: this.pageX + 'px'}
|
|
||||||
}
|
|
||||||
return {left: this.pageX + 'px'}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -383,6 +251,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -394,6 +263,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.num {
|
.num {
|
||||||
|
font-size: 1.3rem;
|
||||||
color: gray;
|
color: gray;
|
||||||
margin-left: .5rem;
|
margin-left: .5rem;
|
||||||
}
|
}
|
||||||
@ -406,6 +276,7 @@ export default {
|
|||||||
|
|
||||||
.collect-list, .recommend-list {
|
.collect-list, .recommend-list {
|
||||||
.item {
|
.item {
|
||||||
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
@ -584,7 +455,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.my-collect-dialog-enter-active,
|
.my-collect-dialog-enter-active,
|
||||||
.my-collect-dialog-leave-active {
|
.my-collect-dialog-leave-active {
|
||||||
transition-duration: 300ms;
|
transition-duration: 300ms;
|
||||||
@ -596,5 +466,17 @@ export default {
|
|||||||
transition-duration: 300ms;
|
transition-duration: 300ms;
|
||||||
transform: translateY(100vh);
|
transform: translateY(100vh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.float-play-enter-active,
|
||||||
|
.float-play-leave-active {
|
||||||
|
transition-duration: 200ms;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-play-enter-from,
|
||||||
|
.float-play-leave-to {
|
||||||
|
transition-duration: 200ms;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="RequestUpdate">
|
<div class="RequestUpdate" id="RequestUpdate">
|
||||||
<BaseHeader>
|
<BaseHeader>
|
||||||
<template v-slot:center>
|
<template v-slot:center>
|
||||||
<span class="f16">求更新</span>
|
<span class="f16">求更新</span>
|
||||||
@ -37,6 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="RequestUpdate"
|
||||||
height="16rem"
|
height="16rem"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
mode="white"
|
mode="white"
|
||||||
|
|||||||
269
src/pages/me/components/CollectMusic.vue
Normal file
269
src/pages/me/components/CollectMusic.vue
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
<template>
|
||||||
|
<div id="CollectMusic">
|
||||||
|
<SlideColumnList
|
||||||
|
:changeActiveIndexUseAnim="false"
|
||||||
|
v-model:active-index="activeIndex"
|
||||||
|
:canMove="slideCanMove">
|
||||||
|
<SlideItemMusic
|
||||||
|
:ref="setItemRef"
|
||||||
|
@showList="isShowList = true"
|
||||||
|
@showShare="isSharing = true"
|
||||||
|
@previous="previous"
|
||||||
|
@next="next"
|
||||||
|
@slideCanMove="e => this.slideCanMove = e"
|
||||||
|
v-model="list[index]"
|
||||||
|
v-model:isLoop="isLoop"
|
||||||
|
v-for="(item,index) in list "/>
|
||||||
|
</SlideColumnList>
|
||||||
|
<from-bottom-dialog
|
||||||
|
mask-mode="lightgray"
|
||||||
|
page-id="CollectMusic"
|
||||||
|
border-radius="1.5rem 1.5rem 0 0"
|
||||||
|
:show-heng-gang="false"
|
||||||
|
height="70vh"
|
||||||
|
v-model="isShowList">
|
||||||
|
<div class="music-list-dialog">
|
||||||
|
<div class="music-list-header">
|
||||||
|
<div class="left">待播清单</div>
|
||||||
|
<div class="right" @click="isLoop = !isLoop">
|
||||||
|
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" alt="">
|
||||||
|
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" alt="">
|
||||||
|
<span>{{ isLoop ? '单曲循环' : '顺序播放' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="l-row"
|
||||||
|
@click="play(index)"
|
||||||
|
:class="{active:activeIndex === index}"
|
||||||
|
v-for="(item,index) in list">
|
||||||
|
<div class="left">
|
||||||
|
<img v-if="activeIndex === index" src="@/assets/img/icon/me/pinlv.gif" alt="" class="play-icon">
|
||||||
|
<div class="name">{{ item.name }}</div>
|
||||||
|
<div class="author">{{ item.author }}</div>
|
||||||
|
</div>
|
||||||
|
<back class="right" mode="gray" img="close"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer" @click="isShowList = false">取消</div>
|
||||||
|
</div>
|
||||||
|
</from-bottom-dialog>
|
||||||
|
|
||||||
|
<Share v-model="isSharing"
|
||||||
|
mode="my-music"
|
||||||
|
ref="share"
|
||||||
|
pageId="GuessMusic"
|
||||||
|
@ShareToFriend="delayShowDialog( e => this.isShowShareToFriend = true)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ShareToFriend pageId="GuessMusic" v-model="isShowShareToFriend"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
|
||||||
|
import Switches from "../../message/components/swtich/switches";
|
||||||
|
import SlideItemMusic from "./SlideItemMusic";
|
||||||
|
import IndicatorLight from "../../../components/slide/IndicatorLight";
|
||||||
|
import SlideColumnList from "../../../components/slide/SlideColumnList";
|
||||||
|
import Share from "../../../components/Share";
|
||||||
|
import ShareToFriend from "../../home/components/ShareToFriend";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "GuessMusic",
|
||||||
|
components: {
|
||||||
|
FromBottomDialog,
|
||||||
|
Switches,
|
||||||
|
SlideItemMusic,
|
||||||
|
IndicatorLight,
|
||||||
|
SlideColumnList,
|
||||||
|
Share,
|
||||||
|
ShareToFriend
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
page2SlideIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
slideCanMove: true,
|
||||||
|
isShowShareToFriend: false,
|
||||||
|
isShowList: false,
|
||||||
|
isSharing: false,
|
||||||
|
isLoop: false,
|
||||||
|
collectSlideIndex: 0,
|
||||||
|
isShowCollectDialog: false,
|
||||||
|
itemRefs: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
activeIndex: {
|
||||||
|
get() {
|
||||||
|
return this.page2SlideIndex
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:page2SlideIndex', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeIndex(newVal, oldVal) {
|
||||||
|
this.itemRefs.map(ref => {
|
||||||
|
ref.togglePlay(false)
|
||||||
|
})
|
||||||
|
this.itemRefs[newVal].togglePlay(true, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
previous() {
|
||||||
|
if (this.activeIndex > 0) {
|
||||||
|
this.play(this.activeIndex - 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
next() {
|
||||||
|
if (this.activeIndex < this.list.length - 1) {
|
||||||
|
this.play(this.activeIndex + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delayShowDialog(cb) {
|
||||||
|
setTimeout(() => {
|
||||||
|
cb()
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
setItemRef(el) {
|
||||||
|
if (el) {
|
||||||
|
this.itemRefs.push(el)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
play(index) {
|
||||||
|
this.activeIndex = index
|
||||||
|
this.itemRefs.map(ref => {
|
||||||
|
ref.togglePlay(false)
|
||||||
|
})
|
||||||
|
this.itemRefs[index].togglePlay(true, true)
|
||||||
|
},
|
||||||
|
pause() {
|
||||||
|
this.itemRefs.map(ref => {
|
||||||
|
ref.togglePlay(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
@import "@/assets/less/index";
|
||||||
|
|
||||||
|
#CollectMusic {
|
||||||
|
//width: 100vw;
|
||||||
|
//height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
overflow: auto;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.music-list-dialog {
|
||||||
|
height: 70vh;
|
||||||
|
@bg-color: #1e1d1d;
|
||||||
|
background: @bg-color;
|
||||||
|
|
||||||
|
.music-list-header {
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
background: @bg-color;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #2a2828;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 5rem;
|
||||||
|
padding: 0 @padding-page;
|
||||||
|
border-radius: 1.5rem 1.5rem 0 0;
|
||||||
|
z-index: 9;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2rem;
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
padding-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-row {
|
||||||
|
background: @bg-color;
|
||||||
|
height: 5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 @padding-page;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: @primary-btn-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.author {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: @second-text-color;
|
||||||
|
margin-left: 2rem;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
width: .6rem;
|
||||||
|
height: .5px;
|
||||||
|
background: @second-text-color;
|
||||||
|
position: absolute;
|
||||||
|
left: -1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-icon {
|
||||||
|
width: 1.5rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: @bg-color;
|
||||||
|
border-top: 1px solid #2a2828;
|
||||||
|
height: 6rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
251
src/pages/me/components/GuessMusic.vue
Normal file
251
src/pages/me/components/GuessMusic.vue
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
<template>
|
||||||
|
<div id="GuessMusic">
|
||||||
|
<SlideColumnList
|
||||||
|
:changeActiveIndexUseAnim="false"
|
||||||
|
v-model:active-index="guessSlideIndex"
|
||||||
|
:canMove="slideCanMove">
|
||||||
|
<SlideItemMusic
|
||||||
|
:ref="setItemRef"
|
||||||
|
@showList="isShowList = true"
|
||||||
|
@showShare="isSharing = true"
|
||||||
|
@previous="previous"
|
||||||
|
@next="next"
|
||||||
|
@slideCanMove="e => this.slideCanMove = e"
|
||||||
|
v-model="list[index]"
|
||||||
|
v-model:isLoop="isLoop"
|
||||||
|
v-for="(item,index) in list "/>
|
||||||
|
</SlideColumnList>
|
||||||
|
<from-bottom-dialog
|
||||||
|
mask-mode="lightgray"
|
||||||
|
page-id="GuessMusic"
|
||||||
|
border-radius="1.5rem 1.5rem 0 0"
|
||||||
|
:show-heng-gang="false"
|
||||||
|
height="70vh"
|
||||||
|
v-model="isShowList">
|
||||||
|
<div class="music-list-dialog">
|
||||||
|
<div class="music-list-header">
|
||||||
|
<div class="left">待播清单</div>
|
||||||
|
<div class="right" @click="isLoop = !isLoop">
|
||||||
|
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" alt="">
|
||||||
|
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" alt="">
|
||||||
|
<span>{{ isLoop ? '单曲循环' : '顺序播放' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="l-row"
|
||||||
|
@click="play(index)"
|
||||||
|
:class="{active:guessSlideIndex === index}"
|
||||||
|
v-for="(item,index) in list">
|
||||||
|
<div class="left">
|
||||||
|
<img v-if="guessSlideIndex === index" src="@/assets/img/icon/me/pinlv.gif" alt="" class="play-icon">
|
||||||
|
<div class="name">{{ item.name }}</div>
|
||||||
|
<div class="author">{{ item.author }}</div>
|
||||||
|
</div>
|
||||||
|
<back class="right" mode="gray" img="close"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer" @click="isShowList = false">取消</div>
|
||||||
|
</div>
|
||||||
|
</from-bottom-dialog>
|
||||||
|
|
||||||
|
<Share v-model="isSharing"
|
||||||
|
mode="my-music"
|
||||||
|
ref="share"
|
||||||
|
pageId="GuessMusic"
|
||||||
|
@ShareToFriend="delayShowDialog( e => this.isShowShareToFriend = true)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ShareToFriend pageId="GuessMusic" v-model="isShowShareToFriend"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
|
||||||
|
import Switches from "../../message/components/swtich/switches";
|
||||||
|
import SlideItemMusic from "./SlideItemMusic";
|
||||||
|
import IndicatorLight from "../../../components/slide/IndicatorLight";
|
||||||
|
import SlideColumnList from "../../../components/slide/SlideColumnList";
|
||||||
|
import Share from "../../../components/Share";
|
||||||
|
import ShareToFriend from "../../home/components/ShareToFriend";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "GuessMusic",
|
||||||
|
components: {
|
||||||
|
FromBottomDialog,
|
||||||
|
Switches,
|
||||||
|
SlideItemMusic,
|
||||||
|
IndicatorLight,
|
||||||
|
SlideColumnList,
|
||||||
|
Share,
|
||||||
|
ShareToFriend
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
slideCanMove: true,
|
||||||
|
isShowShareToFriend: false,
|
||||||
|
isShowList: false,
|
||||||
|
isSharing: false,
|
||||||
|
isLoop: false,
|
||||||
|
guessSlideIndex: 0,
|
||||||
|
isShowCollectDialog: false,
|
||||||
|
itemRefs: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
guessSlideIndex(newVal, oldVal) {
|
||||||
|
this.itemRefs.map(ref => {
|
||||||
|
ref.togglePlay(false)
|
||||||
|
})
|
||||||
|
this.itemRefs[newVal].togglePlay(true, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
previous() {
|
||||||
|
if (this.guessSlideIndex > 0) {
|
||||||
|
this.play(this.guessSlideIndex - 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
next() {
|
||||||
|
if (this.guessSlideIndex < this.list.length - 1) {
|
||||||
|
this.play(this.guessSlideIndex + 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delayShowDialog(cb) {
|
||||||
|
setTimeout(() => {
|
||||||
|
cb()
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
setItemRef(el) {
|
||||||
|
if (el) {
|
||||||
|
this.itemRefs.push(el)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
play(index) {
|
||||||
|
this.guessSlideIndex = index
|
||||||
|
this.itemRefs.map(ref => {
|
||||||
|
ref.togglePlay(false)
|
||||||
|
})
|
||||||
|
this.itemRefs[index].togglePlay(true, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
@import "@/assets/less/index";
|
||||||
|
|
||||||
|
#GuessMusic {
|
||||||
|
//width: 100vw;
|
||||||
|
//height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
overflow: auto;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.music-list-dialog {
|
||||||
|
height: 70vh;
|
||||||
|
@bg-color: #1e1d1d;
|
||||||
|
background: @bg-color;
|
||||||
|
|
||||||
|
.music-list-header {
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
background: @bg-color;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #2a2828;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 5rem;
|
||||||
|
padding: 0 @padding-page;
|
||||||
|
border-radius: 1.5rem 1.5rem 0 0;
|
||||||
|
z-index: 9;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2rem;
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
padding-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-row {
|
||||||
|
background: @bg-color;
|
||||||
|
height: 5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 @padding-page;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: @primary-btn-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.author {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: @second-text-color;
|
||||||
|
margin-left: 2rem;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
width: .6rem;
|
||||||
|
height: .5px;
|
||||||
|
background: @second-text-color;
|
||||||
|
position: absolute;
|
||||||
|
left: -1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-icon {
|
||||||
|
width: 1.5rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: @bg-color;
|
||||||
|
border-top: 1px solid #2a2828;
|
||||||
|
height: 6rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -12,7 +12,10 @@
|
|||||||
<!-- <div class="lyrics-mask" @click="isFullLyrics = true"></div>-->
|
<!-- <div class="lyrics-mask" @click="isFullLyrics = true"></div>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="lyrics-full" v-show="isFullLyrics" @click="isFullLyrics = false">
|
<div class="lyrics-full" v-show="isFullLyrics" @click="isFullLyrics = false">
|
||||||
<div class="list" style="overflow:auto;">
|
<div class="list" style="overflow:auto;"
|
||||||
|
@touchmove="$emit('slideCanMove', false)"
|
||||||
|
@touchend="$emit('slideCanMove', true)"
|
||||||
|
>
|
||||||
<div class="item" v-for="item in lyricsFullTexts">{{ item.c }}</div>
|
<div class="item" v-for="item in lyricsFullTexts">{{ item.c }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -28,7 +31,7 @@
|
|||||||
<img src="@/assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect">
|
<img src="@/assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect">
|
||||||
<span>收藏</span>
|
<span>收藏</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn">
|
<div class="btn" @click="$emit('showShare')">
|
||||||
<img src="@/assets/img/icon/share-white-full.png" alt="">
|
<img src="@/assets/img/icon/share-white-full.png" alt="">
|
||||||
<span>分享</span>
|
<span>分享</span>
|
||||||
</div>
|
</div>
|
||||||
@ -48,17 +51,17 @@
|
|||||||
<div class="end">{{ $durationTime(duration) }}</div>
|
<div class="end">{{ $durationTime(duration) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="options">
|
<div class="options">
|
||||||
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" @click="isLoop = !isLoop">
|
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" @click="$emit('update:isLoop',false)">
|
||||||
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" @click="isLoop = !isLoop">
|
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" @click="$emit('update:isLoop',true)">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<img src="@/assets/img/icon/me/previous.png" @click="t">
|
<img src="@/assets/img/icon/me/previous.png" @click="slide('previous')">
|
||||||
<img v-show="modelValue.is_play" class="control" src="@/assets/img/icon/me/pause.png"
|
<img v-show="isPlay" class="control" src="@/assets/img/icon/me/pause.png"
|
||||||
@click="togglePlay()">
|
@click="togglePlay()">
|
||||||
<img v-show="!modelValue.is_play" class="control" src="@/assets/img/icon/me/play.png"
|
<img v-show="!isPlay" class="control" src="@/assets/img/icon/me/play.png"
|
||||||
@click="togglePlay()">
|
@click="togglePlay()">
|
||||||
<img src="@/assets/img/icon/me/next.png">
|
<img src="@/assets/img/icon/me/next.png" @click="slide('next')">
|
||||||
</div>
|
</div>
|
||||||
<img src="@/assets/img/icon/me/music-list.png">
|
<img src="@/assets/img/icon/me/music-list.png" @click="$emit('showList')">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -77,30 +80,19 @@ export default {
|
|||||||
default: function () {
|
default: function () {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
isLoop: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
slideIndex: 1,
|
slideIndex: 1,
|
||||||
currentMusic: {
|
|
||||||
name: '告白气球',
|
|
||||||
mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3',
|
|
||||||
cover: require('../../../assets/img/music-cover/7.png'),
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false,
|
|
||||||
},
|
|
||||||
collectMusic: [],
|
|
||||||
recommendMusic: [],
|
|
||||||
guessMusic: [],
|
|
||||||
lyricsTexts: [],
|
lyricsTexts: [],
|
||||||
lyricsFullTexts: [],
|
lyricsFullTexts: [],
|
||||||
isShowCollectDialog: false,
|
|
||||||
isPlay: false,
|
isPlay: false,
|
||||||
isAutoPlay: true,
|
isAutoPlay: true,
|
||||||
isLoop: false,
|
|
||||||
isMove: false,
|
isMove: false,
|
||||||
isCollect: false,
|
isCollect: false,
|
||||||
isFullLyrics: false,
|
isFullLyrics: false,
|
||||||
@ -127,12 +119,14 @@ export default {
|
|||||||
this.slideBarWidth = this.$refs.slideBar.clientWidth
|
this.slideBarWidth = this.$refs.slideBar.clientWidth
|
||||||
this.step = this.slideBarWidth / Math.floor(this.duration)
|
this.step = this.slideBarWidth / Math.floor(this.duration)
|
||||||
})
|
})
|
||||||
|
|
||||||
let lrcObj = this.createLrcObj(gaobaiqiqiu);
|
let lrcObj = this.createLrcObj(gaobaiqiqiu);
|
||||||
this.lyricsTexts.push(lrcObj.ms[0])
|
this.lyricsTexts.push(lrcObj.ms[0])
|
||||||
this.lyricsTexts.push(lrcObj.ms[1])
|
this.lyricsTexts.push(lrcObj.ms[1])
|
||||||
lrcObj.ms.map(v => {
|
lrcObj.ms.map(v => {
|
||||||
if (v.c) this.lyricsFullTexts.push(v)
|
if (v.c) this.lyricsFullTexts.push(v)
|
||||||
})
|
})
|
||||||
|
|
||||||
// console.log(lrcObj.ms)
|
// console.log(lrcObj.ms)
|
||||||
this.audio.addEventListener('timeupdate', e => {
|
this.audio.addEventListener('timeupdate', e => {
|
||||||
let currentTime = Math.ceil(e.target.currentTime)
|
let currentTime = Math.ceil(e.target.currentTime)
|
||||||
@ -170,10 +164,19 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
togglePlay(state) {
|
slide(state) {
|
||||||
this.modelValue.is_play = state || !this.modelValue.is_play
|
this.togglePlay(false)
|
||||||
if (this.modelValue.is_play) {
|
this.$emit(state)
|
||||||
this.audio.play()
|
},
|
||||||
|
//TODO DOMException: The play() request was interrupted by a call to pause()
|
||||||
|
//TODO page2会报错,能放歌但是进度条不动
|
||||||
|
async togglePlay(state, reStart = false) {
|
||||||
|
this.isPlay = state !== undefined ? state : !this.isPlay
|
||||||
|
if (reStart) {
|
||||||
|
this.audio.currentTime = 0
|
||||||
|
}
|
||||||
|
if (this.isPlay) {
|
||||||
|
await this.audio.play()
|
||||||
} else {
|
} else {
|
||||||
this.audio.pause()
|
this.audio.pause()
|
||||||
}
|
}
|
||||||
@ -303,6 +306,7 @@ export default {
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
box-shadow: 0 0 1.5rem .5rem #514f4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -412,11 +416,11 @@ export default {
|
|||||||
height: 2rem;
|
height: 2rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
top: -1rem;
|
top: -1rem;
|
||||||
z-index: 11;
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
z-index: 9;
|
z-index: 8;
|
||||||
content: ' ';
|
content: ' ';
|
||||||
height: 1.5px;
|
height: 1.5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -426,7 +430,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bar-line {
|
.bar-line {
|
||||||
z-index: 10;
|
z-index: 9;
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -436,7 +440,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bar-point {
|
.bar-point {
|
||||||
z-index: 10;
|
z-index: 9;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50vw;
|
left: 50vw;
|
||||||
top: -3px;
|
top: -3px;
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Footer v-bind:init-tab="4"/>
|
<Footer v-bind:init-tab="4"/>
|
||||||
|
|
||||||
<from-bottom-dialog v-model="createChatDialog">
|
<from-bottom-dialog page-id="Message" v-model="createChatDialog">
|
||||||
<div class="create-chat-wrapper" v-show="!showJoinedChat">
|
<div class="create-chat-wrapper" v-show="!showJoinedChat">
|
||||||
<Search :isShowText="isShowText"
|
<Search :isShowText="isShowText"
|
||||||
@click="isShowText = true"
|
@click="isShowText = true"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="home-index"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
height="20rem"
|
height="20rem"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="FindAcquaintance">
|
<div class="FindAcquaintance" id="FindAcquaintance">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<back mode="light" @click="back"></back>
|
<back mode="light" @click="back"></back>
|
||||||
<Indicator
|
<Indicator
|
||||||
@ -80,6 +80,7 @@
|
|||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
|
page-id="FindAcquaintance"
|
||||||
v-model="moreOptionDialog"
|
v-model="moreOptionDialog"
|
||||||
:show-heng-gang="false"
|
:show-heng-gang="false"
|
||||||
height="21rem"
|
height="21rem"
|
||||||
|
|||||||
@ -16,6 +16,27 @@ export default class Dom {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addClass(class1) {
|
||||||
|
if (typeof class1 === 'string') {
|
||||||
|
this.els.forEach(el => {
|
||||||
|
el.classList.add(class1)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.els.forEach(el => {
|
||||||
|
el.classList.add(...class1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceClass(class1, class2) {
|
||||||
|
this.els.forEach(el => {
|
||||||
|
el.classList.replace(class1, class2)
|
||||||
|
})
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
find(tag) {
|
find(tag) {
|
||||||
let els = []
|
let els = []
|
||||||
if (this.els.length) {
|
if (this.els.length) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user