2023-12-27 18:21:01 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="mv-list">
|
|
|
|
|
<div class="mv-list-title">
|
|
|
|
|
<h2>推荐MV</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<n-scrollbar :size="100">
|
2024-09-04 15:20:43 +08:00
|
|
|
<div v-loading="loading" class="mv-list-content" :class="setAnimationClass('animate__bounceInLeft')">
|
2024-05-16 18:54:30 +08:00
|
|
|
<div
|
|
|
|
|
v-for="(item, index) in mvList"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
class="mv-item"
|
|
|
|
|
:class="setAnimationClass('animate__bounceIn')"
|
|
|
|
|
:style="setAnimationDelay(index, 30)"
|
|
|
|
|
>
|
2023-12-27 18:21:01 +08:00
|
|
|
<div class="mv-item-img" @click="handleShowMv(item)">
|
2024-05-16 18:54:30 +08:00
|
|
|
<n-image
|
|
|
|
|
class="mv-item-img-img"
|
|
|
|
|
:src="getImgUrl(item.cover, '200y112')"
|
|
|
|
|
lazy
|
|
|
|
|
preview-disabled
|
|
|
|
|
width="200"
|
|
|
|
|
height="112"
|
|
|
|
|
/>
|
2023-12-27 18:21:01 +08:00
|
|
|
<div class="top">
|
|
|
|
|
<div class="play-count">{{ formatNumber(item.playCount) }}</div>
|
|
|
|
|
<i class="iconfont icon-videofill"></i>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mv-item-title">{{ item.name }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</n-scrollbar>
|
|
|
|
|
|
2023-12-27 21:44:32 +08:00
|
|
|
<n-drawer :show="showMv" height="100vh" placement="bottom" :z-index="999999999">
|
2024-09-04 15:20:43 +08:00
|
|
|
<div v-loading="mvLoading" class="mv-detail">
|
2023-12-27 21:44:32 +08:00
|
|
|
<video :src="playMvUrl" controls autoplay></video>
|
2023-12-27 18:21:01 +08:00
|
|
|
<div class="mv-detail-title">
|
|
|
|
|
<div class="title">{{ playMvItem?.name }}</div>
|
|
|
|
|
<button @click="close">
|
|
|
|
|
<i class="iconfont icon-xiasanjiaoxing"></i>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</n-drawer>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { onMounted } from 'vue';
|
|
|
|
|
import { useStore } from 'vuex';
|
|
|
|
|
|
2024-05-16 18:54:30 +08:00
|
|
|
import { getMvUrl, getTopMv } from '@/api/mv';
|
|
|
|
|
import { IMvItem } from '@/type/mv';
|
|
|
|
|
import { formatNumber, getImgUrl, setAnimationClass, setAnimationDelay } from '@/utils';
|
|
|
|
|
|
2024-05-22 12:07:48 +08:00
|
|
|
defineOptions({
|
|
|
|
|
name: 'Mv',
|
|
|
|
|
});
|
|
|
|
|
|
2024-05-16 18:54:30 +08:00
|
|
|
const showMv = ref(false);
|
|
|
|
|
const mvList = ref<Array<IMvItem>>([]);
|
|
|
|
|
const playMvItem = ref<IMvItem>();
|
|
|
|
|
const playMvUrl = ref<string>();
|
|
|
|
|
const store = useStore();
|
2024-09-04 15:20:43 +08:00
|
|
|
const loading = ref(false);
|
2023-12-27 18:21:01 +08:00
|
|
|
|
|
|
|
|
onMounted(async () => {
|
2024-09-04 15:20:43 +08:00
|
|
|
loading.value = true;
|
2024-05-16 18:54:30 +08:00
|
|
|
const res = await getTopMv(30);
|
|
|
|
|
mvList.value = res.data.data;
|
2024-09-04 15:20:43 +08:00
|
|
|
loading.value = false;
|
2024-05-16 18:54:30 +08:00
|
|
|
});
|
2023-12-27 18:21:01 +08:00
|
|
|
|
2024-09-04 15:20:43 +08:00
|
|
|
const mvLoading = ref(false);
|
2023-12-27 18:21:01 +08:00
|
|
|
const handleShowMv = async (item: IMvItem) => {
|
2024-09-04 15:20:43 +08:00
|
|
|
mvLoading.value = true;
|
2024-05-16 18:54:30 +08:00
|
|
|
store.commit('setIsPlay', false);
|
|
|
|
|
store.commit('setPlayMusic', false);
|
|
|
|
|
showMv.value = true;
|
|
|
|
|
const res = await getMvUrl(item.id);
|
2023-12-27 18:21:01 +08:00
|
|
|
playMvItem.value = item;
|
2024-05-16 18:54:30 +08:00
|
|
|
playMvUrl.value = res.data.data.url;
|
2024-09-04 15:20:43 +08:00
|
|
|
mvLoading.value = false;
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
2023-12-27 18:21:01 +08:00
|
|
|
|
|
|
|
|
const close = () => {
|
2024-05-16 18:54:30 +08:00
|
|
|
showMv.value = false;
|
2023-12-27 18:21:01 +08:00
|
|
|
if (store.state.playMusicUrl) {
|
2024-05-16 18:54:30 +08:00
|
|
|
store.commit('setIsPlay', true);
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
2023-12-27 18:21:01 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
.mv-list {
|
2024-05-23 17:12:35 +08:00
|
|
|
@apply relative h-full w-full px-4;
|
2023-12-29 16:04:44 +08:00
|
|
|
|
|
|
|
|
&-title {
|
|
|
|
|
@apply text-xl font-bold;
|
|
|
|
|
}
|
2023-12-27 18:21:01 +08:00
|
|
|
|
|
|
|
|
&-content {
|
2024-05-22 12:07:48 +08:00
|
|
|
@apply grid gap-6 pb-28 mt-2;
|
2023-12-29 16:04:44 +08:00
|
|
|
grid-template-columns: repeat(auto-fill, minmax(14%, 1fr));
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mv-item {
|
2023-12-29 16:04:44 +08:00
|
|
|
@apply p-2 rounded-lg;
|
2024-01-03 22:27:58 +08:00
|
|
|
background-color: #1f1f1f;
|
2023-12-27 18:21:01 +08:00
|
|
|
&-img {
|
2023-12-29 16:04:44 +08:00
|
|
|
@apply rounded-lg overflow-hidden relative;
|
2024-01-03 22:27:58 +08:00
|
|
|
line-height: 0;
|
2023-12-27 18:21:01 +08:00
|
|
|
|
|
|
|
|
&:hover img {
|
2023-12-29 16:04:44 +08:00
|
|
|
@apply hover:scale-110 transition-all duration-300 ease-in-out object-top;
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-img {
|
2024-01-03 22:27:58 +08:00
|
|
|
@apply w-full rounded-lg overflow-hidden;
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.top {
|
|
|
|
|
@apply absolute w-full h-full top-0 left-0 flex justify-center items-center transition-all duration-300 ease-in-out cursor-pointer;
|
2023-12-29 16:04:44 +08:00
|
|
|
background-color: #0000009b;
|
2023-12-27 18:21:01 +08:00
|
|
|
opacity: 0;
|
|
|
|
|
|
|
|
|
|
i {
|
2023-12-29 16:04:44 +08:00
|
|
|
font-size: 40px;
|
2023-12-27 18:21:01 +08:00
|
|
|
transition: all 0.5s ease-in-out;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
@apply opacity-100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover i {
|
2023-12-29 16:04:44 +08:00
|
|
|
@apply transform scale-150 opacity-80;
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.play-count {
|
|
|
|
|
position: absolute;
|
2024-01-03 22:27:58 +08:00
|
|
|
top: 20px;
|
2023-12-27 18:21:01 +08:00
|
|
|
left: 10px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&-title {
|
|
|
|
|
@apply p-2 text-sm text-white truncate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mv-detail {
|
|
|
|
|
@apply w-full h-full bg-black relative;
|
|
|
|
|
|
|
|
|
|
&-title {
|
2023-12-27 21:44:32 +08:00
|
|
|
@apply absolute w-full left-0 flex justify-between h-16 px-6 py-2 text-xl font-bold items-center z-50 transition-all duration-300 ease-in-out -top-24;
|
|
|
|
|
background: linear-gradient(0, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%);
|
2023-12-27 18:21:01 +08:00
|
|
|
button .icon-xiasanjiaoxing {
|
2023-12-27 21:44:32 +08:00
|
|
|
@apply text-3xl;
|
2023-12-27 18:21:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
button:hover {
|
|
|
|
|
@apply text-green-400;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
video {
|
|
|
|
|
@apply w-full h-full;
|
|
|
|
|
}
|
2023-12-27 21:44:32 +08:00
|
|
|
video:hover + .mv-detail-title {
|
|
|
|
|
@apply top-0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mv-detail-title:hover {
|
|
|
|
|
@apply top-0;
|
|
|
|
|
}
|
2024-05-16 18:54:30 +08:00
|
|
|
}
|
2024-05-23 17:12:35 +08:00
|
|
|
|
|
|
|
|
.mobile {
|
|
|
|
|
.mv-list-content {
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-16 18:54:30 +08:00
|
|
|
</style>
|