Browse Source

音乐收藏页面

pull/19/head
zyronon 4 years ago
parent
commit
a5bf5939ca
  1. 6
      src/App.vue
  2. 2
      src/assets/scss/utils.less
  3. 19
      src/components/BaseButton.vue
  4. 4
      src/mock/index.js
  5. 18
      src/pages/me/Me.vue
  6. 304
      src/pages/me/collect/MusicCollect.vue
  7. 47
      src/pages/me/collect/VideoCollect.vue
  8. 6
      src/router/index.js

6
src/App.vue

@ -45,7 +45,7 @@ export default { @@ -45,7 +45,7 @@ export default {
this.$store.commit('setMaskDialog', {state: false, mode: this.maskDialogMode})
//footer5
let noAnimation = ['/', '/home', '/me', '/attention', '/message', '/publish','/home/live']
let noAnimation = ['/', '/home', '/me', '/attention', '/message', '/publish', '/home/live']
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
return this.transitionName = ''
}
@ -82,12 +82,16 @@ export default { @@ -82,12 +82,16 @@ export default {
'/message/chat',
'/message/chat-detail',
'/set-remark',
'/me/request-update',
'/me/right-menu/look-history',
'/me/right-menu/minor-protection/index',
'/me/right-menu/minor-protection/detail-setting',
'/me/right-menu/minor-protection/trigger-time',
'/me/right-menu/setting',
'/me/collect/video-collect',
'/me/collect/music-collect',
'/login',
'/login/other',
'/login/password',

2
src/assets/scss/utils.less

@ -85,7 +85,7 @@ margin @@ -85,7 +85,7 @@ margin
.mt(@n, (@i + 1));
}
.mb(5);
.mb(7);
.mb(@n, @i: 1) when (@i =< @n) {
.mb@{i}r {
margin-bottom: (1rem * @i) !important;

19
src/components/BaseButton.vue

@ -39,6 +39,11 @@ export default { @@ -39,6 +39,11 @@ export default {
type: Boolean,
default: true
},
size: {
type: String,
default: 'normal'
//small
},
},
data() {
return {}
@ -50,6 +55,7 @@ export default { @@ -50,6 +55,7 @@ export default {
this.active ? '' : 'no-active',
this.border ? '' : 'no-border',
this.disabled && 'disabled',
this.size
]
},
showText() {
@ -121,7 +127,7 @@ export default { @@ -121,7 +127,7 @@ export default {
}
&.dark2 {
border:1px solid @second-btn-color;
border: 1px solid @second-btn-color;
background: white;
color: #000;
}
@ -140,8 +146,9 @@ export default { @@ -140,8 +146,9 @@ export default {
background: rgb(27, 177, 228);
color: white;
}
&.webo {
background: rgb(242,95,67);
background: rgb(242, 95, 67);
color: white;
}
@ -224,8 +231,14 @@ export default { @@ -224,8 +231,14 @@ export default {
}
&.no-border {
border: none!important;
border: none !important;
background: rgb(212 212 212 / 36%);
}
&.small {
font-size: 1.2rem;
width: 6.2rem;
height: 2.6rem;
}
}
</style>

4
src/mock/index.js

@ -114,11 +114,11 @@ Mock.mock(/collect/, options => { @@ -114,11 +114,11 @@ Mock.mock(/collect/, options => {
return Mock.mock({
data: {
video: {
total: 0,
total: resource.videos.length,
list: resource.videos,
},
music: {
total: 0,
total: resource.music.length,
list: resource.music,
}
}, code: 200, msg: '',

18
src/pages/me/Me.vue

@ -158,20 +158,20 @@ @@ -158,20 +158,20 @@
<span>只有你能看到自己的收藏列表</span>
</div>
<div class="collect" ref="collect">
<div class="video" v-if=" videos.collect.video.list.length">
<div class="top" >
<div class="video" v-if=" videos.collect.video.total">
<div class="top" @click="$nav('/me/collect/video-collect')">
<div class="left">
<img src="../../assets/img/icon/me/video-whitegray.png" alt="">
<span>视频</span>
</div>
<div class="right">
<span>全部</span>
<back direction="right" ></back>
<back direction="right"></back>
</div>
</div>
<div class="list">
<div class="item"
v-for="i in videos.collect.video.list.length>3?videos.collect.video.list.slice(0,3):videos.collect.video.list">
v-for="i in videos.collect.video.total>3?videos.collect.video.list.slice(0,3):videos.collect.video.list">
<img class="poster" :src="$imgPreview(i.video+videoPoster)" alt="">
<div class="num">
<img class="love" src="../../assets/img/icon/love.svg" alt="">
@ -181,20 +181,20 @@ @@ -181,20 +181,20 @@
</div>
</div>
<div class="music" v-if=" videos.collect.music.list.length">
<div class="top">
<div class="music" v-if=" videos.collect.music.total">
<div class="top" @click="$nav('/me/collect/music-collect')">
<div class="left">
<img src="../../assets/img/icon/me/music-whitegray.png" alt="">
<span>音乐</span>
</div>
<div class="right">
<span>全部</span>
<back direction="right" ></back>
<back direction="right"></back>
</div>
</div>
<div class="list">
<div class="item"
v-for="i in videos.collect.music.list.length>3?videos.collect.music.list.slice(0,3):videos.collect.music.list">
v-for="i in videos.collect.music.total>3?videos.collect.music.list.slice(0,3):videos.collect.music.list">
<img class="poster" :src="$imgPreview(i.cover)" alt="">
<div class="title">{{ i.name }}</div>
</div>
@ -505,7 +505,7 @@ export default { @@ -505,7 +505,7 @@ export default {
if (newVal === 3) {
if (videoOb.video.total === -1) {
this.loadings['loading' + newVal] = true
let res = await this.$api.videos.collect({pageNo: this.videos.collect.pageNo, pageSize: this.pageSize,})
let res = await this.$api.videos.collect()
if (res.code === this.SUCCESS) this.videos.collect = res.data
}
} else {

304
src/pages/me/collect/MusicCollect.vue

@ -0,0 +1,304 @@ @@ -0,0 +1,304 @@
<template>
<div class="MusicCollect">
<BaseHeader>
<template v-slot:center>
<span class="f16">音乐收藏</span>
</template>
</BaseHeader>
<div class="content">
<div class="list">
<div class="item" v-for="(item,index) in list" @click="togglePlay(item,list)">
<div class="music">
<div class="cover-wrapper">
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
<img v-if="!item.is_play" src="@/assets/img/icon/play-white.png" alt="" class="play">
<img v-if="item.is_play" src="@/assets/img/icon/pause-white.png" alt="" class="play">
</div>
<div class="desc">
<span class="name">{{ item.name }}</span>
<div class="author">{{ item.author }}</div>
<div class="desc-bottom">
<div class="duration">{{ $duration(item.duration) }}</div>
</div>
</div>
</div>
<div class="option">
<img src="@/assets/img/icon/menu2-white.png" alt="" @click.stop="$nav('/home/music')">
</div>
</div>
</div>
<no-more class="mb7r"/>
</div>
<div class="float-play-music" v-if="currentItem">
<div class="process" :style="{width : process + 'px'}"></div>
<div class="music-wrapper">
<div class="music">
<div class="cover-wrapper">
<img v-lazy="$imgPreview(currentItem.cover)" alt="" class="cover">
<img v-if="!currentItem.is_play" src="@/assets/img/icon/play-white.png" alt="" class="play">
<img v-if="currentItem.is_play" src="@/assets/img/icon/pause-white.png" alt="" class="play">
</div>
<div class="desc">
<span class="name">{{ currentItem.name }}</span>
<div class="desc-bottom">
<div class="duration">{{ $duration(currentItem.duration) }}</div>
</div>
</div>
</div>
<div class="option">
<b-button type="primary" size="small">使用</b-button>
</div>
</div>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "MusicCollect",
components: {},
props: {},
data() {
return {
list: [],
audio: new Audio(),
currentItem: null,
step: null,
process: 0,
}
},
computed: {
...mapState(['bodyWidth'])
},
created() {
this.getData()
},
mounted() {
this.audio.addEventListener('loadedmetadata', e => {
this.currentItem.duration = this.audio.duration
this.step = this.bodyWidth / Math.floor(this.audio.duration)
})
this.audio.addEventListener('timeupdate', e => {
this.process = Math.ceil(e.target.currentTime) * this.step
})
},
methods: {
async getData() {
let res = await this.$api.videos.collect()
if (res.code === this.SUCCESS) {
this.list = res.data.music.list
}
},
togglePlay(item, list) {
list.map(v => {
if (v.name !== item.name) {
v.is_play = false
}
})
item.is_play = !item.is_play
if (item.is_play) {
if (this.currentItem) {
if (this.currentItem.name !== item.name) {
this.audio.pause()
this.audio.src = item.mp3
this.audio.currentTime = 0
}
} else {
this.audio.pause()
this.audio.src = item.mp3
this.audio.currentTime = 0
}
this.audio.play();
this.audio.addEventListener('ended', () => item.is_play = false)
} else {
this.stopPlay()
}
this.currentItem = item
},
stopPlay() {
this.audio.pause()
// this.audio.currentTime = 0
this.audio.removeEventListener('ended', null)
}
},
unmounted() {
this.stopPlay()
},
}
</script>
<style scoped lang="less">
@import "@/assets/scss/index";
.MusicCollect {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
color: white;
font-size: 1.4rem;
.content {
padding-top: 6rem;
.list {
.item {
padding: 2rem 1.5rem;
padding-bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
.music {
display: flex;
.cover-wrapper {
margin-right: 1rem;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.play {
width: 3rem;
height: 3rem;
position: absolute;
}
.cover {
border-radius: .2rem;
@width: 6rem;
width: @width;
height: @width;
}
}
.desc {
display: flex;
flex-direction: column;
justify-content: space-between;
.name {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 40vw;
}
.author, .desc-bottom {
font-size: 1.2rem;
color: @second-text-color;
}
.desc-bottom {
display: flex;
.duration {
margin-right: 1.4rem;
position: relative;
}
}
}
}
.option {
img {
width: 2rem;
height: 2rem;
margin-left: 2rem;
}
}
}
}
}
.float-play-music {
position: fixed;
bottom: 0;
width: 100vw;
background: @main-bg;
display: flex;
align-items: center;
justify-content: space-between;
.process {
position: absolute;
top: 0;
z-index: 2;
height: 1px;
width: 50vw;
background: yellow;
}
.music-wrapper {
width: 100vw;
border-top: 1px solid #414141;
padding: 1rem 1.5rem;
display: flex;
align-items: center;
justify-content: space-between;
.music {
display: flex;
.cover-wrapper {
margin-right: 1rem;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.play {
width: 3rem;
height: 3rem;
position: absolute;
}
.cover {
border-radius: .2rem;
@width: 5rem;
width: @width;
height: @width;
}
}
.desc {
display: flex;
flex-direction: column;
justify-content: space-between;
.name {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 40vw;
}
.author, .desc-bottom {
font-size: 1.2rem;
color: @second-text-color;
}
.desc-bottom {
display: flex;
.duration {
margin-right: 1.4rem;
position: relative;
}
}
}
}
.option {
.button {
}
}
}
}
}
</style>

47
src/pages/me/collect/VideoCollect.vue

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
<template>
<div class="VideoCollect">
<BaseHeader>
<template v-slot:center>
<span class="f16">申报学校信息</span>
</template>
</BaseHeader>
<div class="content">
</div>
</div>
</template>
<script>
export default {
name: "VideoCollect",
components: {},
props: {
modelValue: false
},
data() {
return {}
},
computed: {},
created() {
},
methods: {}
}
</script>
<style scoped lang="less">
@import "../../../assets/scss/index";
.VideoCollect {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
color: white;
font-size: 1.4rem;
.content {
padding-top: 6rem;
}
}
</style>

6
src/router/index.js

@ -53,6 +53,8 @@ import Test4 from "../pages/Test4"; @@ -53,6 +53,8 @@ import Test4 from "../pages/Test4";
import Search from "../pages/home/SearchPage";
import LivePage from "../pages/home/LivePage";
import Test5 from "../pages/Test5";
import MusicCollect from "../pages/me/collect/MusicCollect";
import VideoCollect from "../pages/me/collect/VideoCollect";
const routes = [
// {path: '', component: Music},
@ -101,11 +103,15 @@ const routes = [ @@ -101,11 +103,15 @@ const routes = [
{path: '/scan', component: Scan},
{path: '/face-to-face', component: FaceToFace},
{path: '/set-remark', component: SetRemark},
{path: '/me/right-menu/look-history', component: LookHistory},
{path: '/me/right-menu/minor-protection/index', component: MinorProtectionIndex},
{path: '/me/right-menu/minor-protection/detail-setting', component: MinorProtectionDetailSetting},
{path: '/me/right-menu/minor-protection/trigger-time', component: TriggerTime},
{path: '/me/right-menu/setting', component: Setting},
{path: '/me/collect/music-collect', component: MusicCollect},
{path: '/me/collect/video-collect', component: VideoCollect},
{path: '/login', component: Login},
{path: '/login/other', component: OtherLogin},
{path: '/login/password', component: PasswordLogin},

Loading…
Cancel
Save