mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-18 11:37:31 +08:00
🦄 refactor: 适配 web移动端 改造
This commit is contained in:
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
--animate-delay: 0.5s;
|
--animate-delay: 0.5s;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
+13
-1
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app">
|
<div class="app" :class="isMobile ? 'mobile' : ''">
|
||||||
<audio id="MusicAudio" ref="audioRef" :src="playMusicUrl" :autoplay="play"></audio>
|
<audio id="MusicAudio" ref="audioRef" :src="playMusicUrl" :autoplay="play"></audio>
|
||||||
<n-config-provider :theme="darkTheme">
|
<n-config-provider :theme="darkTheme">
|
||||||
<n-dialog-provider>
|
<n-dialog-provider>
|
||||||
@@ -16,6 +16,8 @@ import { darkTheme } from 'naive-ui';
|
|||||||
|
|
||||||
import store from '@/store';
|
import store from '@/store';
|
||||||
|
|
||||||
|
import { isMobile } from './utils';
|
||||||
|
|
||||||
const playMusicUrl = computed(() => store.state.playMusicUrl as string);
|
const playMusicUrl = computed(() => store.state.playMusicUrl as string);
|
||||||
// 是否播放
|
// 是否播放
|
||||||
const play = computed(() => store.state.play as boolean);
|
const play = computed(() => store.state.play as boolean);
|
||||||
@@ -35,4 +37,14 @@ div {
|
|||||||
.app {
|
.app {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.text-base {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.html:has(.mobile) {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-drawer :show="show" height="70vh" placement="bottom" :drawer-style="{ backgroundColor: 'transparent' }">
|
<n-drawer
|
||||||
|
:show="show"
|
||||||
|
:height="isMobile ? '100vh' : '70vh'"
|
||||||
|
placement="bottom"
|
||||||
|
:drawer-style="{ backgroundColor: 'transparent' }"
|
||||||
|
>
|
||||||
<div class="music-page">
|
<div class="music-page">
|
||||||
<i class="iconfont icon-icon_error music-close" @click="close"></i>
|
<i class="iconfont icon-icon_error music-close" @click="close"></i>
|
||||||
<div class="music-title">{{ name }}</div>
|
<div class="music-title text-el">{{ name }}</div>
|
||||||
<!-- 歌单歌曲列表 -->
|
<!-- 歌单歌曲列表 -->
|
||||||
<div class="music-list">
|
<div class="music-list">
|
||||||
<n-scrollbar>
|
<n-scrollbar>
|
||||||
@@ -25,7 +30,7 @@
|
|||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
import SongItem from '@/components/common/SongItem.vue';
|
import SongItem from '@/components/common/SongItem.vue';
|
||||||
import { setAnimationClass, setAnimationDelay } from '@/utils';
|
import { isMobile, setAnimationClass, setAnimationDelay } from '@/utils';
|
||||||
|
|
||||||
import PlayBottom from './common/PlayBottom.vue';
|
import PlayBottom from './common/PlayBottom.vue';
|
||||||
|
|
||||||
@@ -78,4 +83,10 @@ const close = () => {
|
|||||||
height: calc(100% - 60px);
|
height: calc(100% - 60px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.music-page {
|
||||||
|
@apply px-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -74,4 +74,10 @@ onMounted(() => {
|
|||||||
@apply block text-center;
|
@apply block text-center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.play-list-type {
|
||||||
|
@apply mx-0 w-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 推荐歌手 -->
|
<!-- 推荐歌手 -->
|
||||||
|
<n-scrollbar :size="100" :x-scrollable="true">
|
||||||
<div class="recommend-singer">
|
<div class="recommend-singer">
|
||||||
<div class="recommend-singer-list">
|
<div class="recommend-singer-list">
|
||||||
<div
|
<div
|
||||||
@@ -15,10 +16,10 @@
|
|||||||
class="recommend-singer-item-count p-2 text-base text-gray-200 z-10 cursor-pointer"
|
class="recommend-singer-item-count p-2 text-base text-gray-200 z-10 cursor-pointer"
|
||||||
@click="showMusic = true"
|
@click="showMusic = true"
|
||||||
>
|
>
|
||||||
<div class="font-bold text-xl">每日推荐列表</div>
|
<div class="font-bold text-xl">每日推荐</div>
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<p v-for="item in dayRecommendData?.dailySongs.slice(0, 8)" :key="item.id" class="text-el">
|
<p v-for="item in dayRecommendData?.dailySongs.slice(0, 5)" :key="item.id" class="text-el">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
:song-list="dayRecommendData?.dailySongs"
|
:song-list="dayRecommendData?.dailySongs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</n-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -110,7 +112,7 @@ const toSearchSinger = (keyword: string) => {
|
|||||||
height: 280px;
|
height: 280px;
|
||||||
}
|
}
|
||||||
&-item {
|
&-item {
|
||||||
@apply flex-1 h-full rounded-3xl p-5 mr-5 flex flex-col justify-between;
|
@apply flex-1 h-full rounded-3xl p-5 mr-5 flex flex-col justify-between overflow-hidden;
|
||||||
&-bg {
|
&-bg {
|
||||||
@apply bg-gray-900 bg-no-repeat bg-cover bg-center rounded-3xl absolute w-full h-full top-0 left-0 z-0;
|
@apply bg-gray-900 bg-no-repeat bg-cover bg-center rounded-3xl absolute w-full h-full top-0 left-0 z-0;
|
||||||
filter: brightness(60%);
|
filter: brightness(60%);
|
||||||
@@ -123,4 +125,17 @@ const toSearchSinger = (keyword: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile .recommend-singer {
|
||||||
|
&-list {
|
||||||
|
height: 180px;
|
||||||
|
@apply ml-4;
|
||||||
|
}
|
||||||
|
&-item {
|
||||||
|
@apply p-4 rounded-xl;
|
||||||
|
&-bg {
|
||||||
|
@apply rounded-xl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,14 +4,18 @@
|
|||||||
<title-bar v-if="isElectron" />
|
<title-bar v-if="isElectron" />
|
||||||
<div class="layout-main-page" :class="isElectron ? '' : 'pt-6'">
|
<div class="layout-main-page" :class="isElectron ? '' : 'pt-6'">
|
||||||
<!-- 侧边菜单栏 -->
|
<!-- 侧边菜单栏 -->
|
||||||
<app-menu class="menu" :menus="menus" />
|
<app-menu v-if="!isMobile" class="menu" :menus="menus" />
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<!-- 搜索栏 -->
|
<!-- 搜索栏 -->
|
||||||
<search-bar />
|
<search-bar />
|
||||||
<!-- 主页面路由 -->
|
<!-- 主页面路由 -->
|
||||||
<div class="main-content bg-black" :native-scrollbar="false">
|
<div class="main-content bg-black" :native-scrollbar="false">
|
||||||
<n-message-provider>
|
<n-message-provider>
|
||||||
<router-view v-slot="{ Component }" class="main-page" :class="route.meta.noScroll ? 'pr-3' : ''">
|
<router-view
|
||||||
|
v-slot="{ Component }"
|
||||||
|
class="main-page"
|
||||||
|
:class="route.meta.noScroll && !isMobile ? 'pr-3' : ''"
|
||||||
|
>
|
||||||
<keep-alive :include="keepAliveInclude">
|
<keep-alive :include="keepAliveInclude">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
@@ -19,6 +23,7 @@
|
|||||||
</n-message-provider>
|
</n-message-provider>
|
||||||
</div>
|
</div>
|
||||||
<play-bottom height="5rem" />
|
<play-bottom height="5rem" />
|
||||||
|
<app-menu v-if="isMobile" class="menu" :menus="menus" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 底部音乐播放 -->
|
<!-- 底部音乐播放 -->
|
||||||
@@ -33,6 +38,7 @@ import { useStore } from 'vuex';
|
|||||||
|
|
||||||
import PlayBottom from '@/components/common/PlayBottom.vue';
|
import PlayBottom from '@/components/common/PlayBottom.vue';
|
||||||
import homeRouter from '@/router/home';
|
import homeRouter from '@/router/home';
|
||||||
|
import { isMobile } from '@/utils';
|
||||||
|
|
||||||
const keepAliveInclude = computed(() =>
|
const keepAliveInclude = computed(() =>
|
||||||
homeRouter
|
homeRouter
|
||||||
@@ -135,18 +141,23 @@ const playMusicEvent = async () => {
|
|||||||
&-page {
|
&-page {
|
||||||
@apply flex flex-1 overflow-hidden;
|
@apply flex flex-1 overflow-hidden;
|
||||||
}
|
}
|
||||||
.menu {
|
|
||||||
width: 90px;
|
|
||||||
}
|
|
||||||
.main {
|
.main {
|
||||||
@apply flex-1 box-border flex flex-col;
|
@apply flex-1 box-border flex flex-col overflow-hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
&-content {
|
&-content {
|
||||||
@apply box-border flex-1 overflow-hidden;
|
@apply box-border flex-1 overflow-hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.n-scrollbar-content) {
|
// :deep(.n-scrollbar-content) {
|
||||||
@apply pr-3;
|
// @apply pr-3;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.layout-main {
|
||||||
|
&-page {
|
||||||
|
@apply pt-4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -82,4 +82,25 @@ const iconStyle = (index: number) => {
|
|||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
transition: 0.2s ease-in-out;
|
transition: 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.app-menu {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100vw;
|
||||||
|
position: relative;
|
||||||
|
z-index: 999999;
|
||||||
|
background-color: #000;
|
||||||
|
&-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&-list {
|
||||||
|
@apply flex justify-between;
|
||||||
|
}
|
||||||
|
&-item {
|
||||||
|
&-link {
|
||||||
|
@apply my-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -179,4 +179,16 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
#drawer-target {
|
||||||
|
@apply flex-col p-4 pt-8;
|
||||||
|
.music-img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.music-lrc {
|
||||||
|
height: calc(100vh - 260px) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,13 +25,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="music-buttons">
|
<div class="music-buttons">
|
||||||
<div @click="handlePrev">
|
<div class="music-buttons-prev" @click="handlePrev">
|
||||||
<i class="iconfont icon-prev"></i>
|
<i class="iconfont icon-prev"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="music-buttons-play" @click="playMusicEvent">
|
<div class="music-buttons-play" @click="playMusicEvent">
|
||||||
<i class="iconfont icon" :class="play ? 'icon-stop' : 'icon-play'"></i>
|
<i class="iconfont icon" :class="play ? 'icon-stop' : 'icon-play'"></i>
|
||||||
</div>
|
</div>
|
||||||
<div @click="handleEnded">
|
<div class="music-buttons-next" @click="handleEnded">
|
||||||
<i class="iconfont icon-next"></i>
|
<i class="iconfont icon-next"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
</template>
|
</template>
|
||||||
解析播放
|
解析播放
|
||||||
</n-tooltip> -->
|
</n-tooltip> -->
|
||||||
<n-tooltip trigger="hover" :z-index="9999999">
|
<n-tooltip class="music-lyric" trigger="hover" :z-index="9999999">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<i class="iconfont ri-netease-cloud-music-line" @click="openLyric"></i>
|
<i class="iconfont ri-netease-cloud-music-line" @click="openLyric"></i>
|
||||||
</template>
|
</template>
|
||||||
@@ -305,4 +305,36 @@ const setMusicFull = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.music-play-bar {
|
||||||
|
@apply px-4;
|
||||||
|
bottom: 70px;
|
||||||
|
}
|
||||||
|
.music-time {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ri-netease-cloud-music-line {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.audio-volume {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.audio-button {
|
||||||
|
@apply mx-0;
|
||||||
|
}
|
||||||
|
.music-buttons {
|
||||||
|
@apply m-0;
|
||||||
|
&-prev,
|
||||||
|
&-next {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&-play {
|
||||||
|
@apply m-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.music-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -145,4 +145,10 @@ const selectItem = async (key: string) => {
|
|||||||
.search-box-input {
|
.search-box-input {
|
||||||
@apply relative;
|
@apply relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.search-box {
|
||||||
|
@apply pl-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ interface State {
|
|||||||
playListIndex: number;
|
playListIndex: number;
|
||||||
setData: any;
|
setData: any;
|
||||||
lyric: any;
|
lyric: any;
|
||||||
|
isMobile: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state: State = {
|
const state: State = {
|
||||||
@@ -30,6 +31,7 @@ const state: State = {
|
|||||||
playListIndex: 0,
|
playListIndex: 0,
|
||||||
setData: null,
|
setData: null,
|
||||||
lyric: {},
|
lyric: {},
|
||||||
|
isMobile: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const windowData = window as any;
|
const windowData = window as any;
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
import store from '@/store';
|
||||||
|
|
||||||
// 设置歌手背景图片
|
// 设置歌手背景图片
|
||||||
export const setBackgroundImg = (url: String) => {
|
export const setBackgroundImg = (url: String) => {
|
||||||
return `background-image:url(${url})`;
|
return `background-image:url(${url})`;
|
||||||
@@ -59,3 +63,15 @@ export const getImgUrl = computed(() => (url: string | undefined, size: string =
|
|||||||
const imgUrl = encodeURIComponent(`${url}?param=${size}`);
|
const imgUrl = encodeURIComponent(`${url}?param=${size}`);
|
||||||
return `${bdUrl}${imgUrl}`;
|
return `${bdUrl}${imgUrl}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const isMobile = computed(() => {
|
||||||
|
const flag = navigator.userAgent.match(
|
||||||
|
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i,
|
||||||
|
);
|
||||||
|
|
||||||
|
store.state.isMobile = !!flag;
|
||||||
|
|
||||||
|
// 给html标签 添加mobile
|
||||||
|
if (flag) document.documentElement.classList.add('mobile');
|
||||||
|
return !!flag;
|
||||||
|
});
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const { delMusic, musicList } = useMusicHistory();
|
|||||||
.history-page {
|
.history-page {
|
||||||
@apply h-full w-full pt-2;
|
@apply h-full w-full pt-2;
|
||||||
.title {
|
.title {
|
||||||
@apply text-xl font-bold;
|
@apply pl-4 text-xl font-bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-list-content {
|
.history-list-content {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-scrollbar :size="100">
|
<n-scrollbar :size="100" :x-scrollable="false">
|
||||||
<div class="main-page">
|
<div class="main-page">
|
||||||
<!-- 推荐歌手 -->
|
<!-- 推荐歌手 -->
|
||||||
<recommend-singer />
|
<recommend-singer />
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<!-- 歌单分类列表 -->
|
<!-- 歌单分类列表 -->
|
||||||
<playlist-type />
|
<playlist-type v-if="!isMobile" />
|
||||||
<!-- 本周最热音乐 -->
|
<!-- 本周最热音乐 -->
|
||||||
<recommend-songlist />
|
<recommend-songlist />
|
||||||
<!-- 推荐最新专辑 -->
|
<!-- 推荐最新专辑 -->
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { isMobile } from '@/utils';
|
||||||
|
|
||||||
const RecommendSinger = defineAsyncComponent(() => import('@/components/RecommendSinger.vue'));
|
const RecommendSinger = defineAsyncComponent(() => import('@/components/RecommendSinger.vue'));
|
||||||
const PlaylistType = defineAsyncComponent(() => import('@/components/PlaylistType.vue'));
|
const PlaylistType = defineAsyncComponent(() => import('@/components/PlaylistType.vue'));
|
||||||
const RecommendSonglist = defineAsyncComponent(() => import('@/components/RecommendSonglist.vue'));
|
const RecommendSonglist = defineAsyncComponent(() => import('@/components/RecommendSonglist.vue'));
|
||||||
@@ -27,9 +29,13 @@ defineOptions({
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.main-page {
|
.main-page {
|
||||||
@apply h-full w-full;
|
@apply h-full w-full overflow-hidden;
|
||||||
}
|
}
|
||||||
.main-content {
|
.main-content {
|
||||||
@apply mt-6 flex mb-28;
|
@apply mt-6 flex mb-28;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile .main-content {
|
||||||
|
@apply flex-col mx-4;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ defineOptions({
|
|||||||
const recommendList = ref();
|
const recommendList = ref();
|
||||||
const showMusic = ref(false);
|
const showMusic = ref(false);
|
||||||
|
|
||||||
const recommendItem = ref<IRecommendItem>();
|
const recommendItem = ref<IRecommendItem | null>();
|
||||||
const listDetail = ref<IListDetail>();
|
const listDetail = ref<IListDetail | null>();
|
||||||
const selectRecommendItem = async (item: IRecommendItem) => {
|
const selectRecommendItem = async (item: IRecommendItem) => {
|
||||||
|
recommendItem.value = null;
|
||||||
|
listDetail.value = null;
|
||||||
showMusic.value = true;
|
showMusic.value = true;
|
||||||
const { data } = await getListDetail(item.id);
|
const { data } = await getListDetail(item.id);
|
||||||
recommendItem.value = item;
|
recommendItem.value = item;
|
||||||
@@ -98,7 +100,7 @@ watch(
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.list-page {
|
.list-page {
|
||||||
@apply relative h-full w-full;
|
@apply relative h-full w-full px-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recommend {
|
.recommend {
|
||||||
@@ -149,4 +151,10 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.recommend-list {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(25%, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useRouter } from 'vue-router';
|
|||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
import { checkQr, createQr, getQrKey, getUserDetail, loginByCellphone } from '@/api/login';
|
import { checkQr, createQr, getQrKey, getUserDetail, loginByCellphone } from '@/api/login';
|
||||||
import { setAnimationClass } from '@/utils';
|
import { isMobile, setAnimationClass } from '@/utils';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
@@ -71,7 +71,7 @@ const timerIsQr = (key: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 是否扫码登陆
|
// 是否扫码登陆
|
||||||
const isQr = ref(true);
|
const isQr = ref(!isMobile.value);
|
||||||
const chooseQr = () => {
|
const chooseQr = () => {
|
||||||
isQr.value = !isQr.value;
|
isQr.value = !isQr.value;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const close = () => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.mv-list {
|
.mv-list {
|
||||||
@apply relative h-full w-full;
|
@apply relative h-full w-full px-4;
|
||||||
|
|
||||||
&-title {
|
&-title {
|
||||||
@apply text-xl font-bold;
|
@apply text-xl font-bold;
|
||||||
@@ -173,4 +173,10 @@ const close = () => {
|
|||||||
@apply top-0;
|
@apply top-0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.mv-list-content {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search-page">
|
<div class="search-page">
|
||||||
<n-layout class="hot-search" :class="setAnimationClass('animate__fadeInDown')" :native-scrollbar="false">
|
<n-layout
|
||||||
|
v-if="isMobile ? !searchDetail : true"
|
||||||
|
class="hot-search"
|
||||||
|
:class="setAnimationClass('animate__fadeInDown')"
|
||||||
|
:native-scrollbar="false"
|
||||||
|
>
|
||||||
<div class="title">热搜列表</div>
|
<div class="title">热搜列表</div>
|
||||||
<div class="hot-search-list">
|
<div class="hot-search-list">
|
||||||
<template v-for="(item, index) in hotSearchData?.data" :key="index">
|
<template v-for="(item, index) in hotSearchData?.data" :key="index">
|
||||||
@@ -17,7 +22,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-layout>
|
</n-layout>
|
||||||
<!-- 搜索到的歌曲列表 -->
|
<!-- 搜索到的歌曲列表 -->
|
||||||
<n-layout class="search-list" :class="setAnimationClass('animate__fadeInUp')" :native-scrollbar="false">
|
<n-layout
|
||||||
|
v-if="isMobile ? searchDetail : true"
|
||||||
|
class="search-list"
|
||||||
|
:class="setAnimationClass('animate__fadeInUp')"
|
||||||
|
:native-scrollbar="false"
|
||||||
|
>
|
||||||
<div class="title">{{ hotKeyword }}</div>
|
<div class="title">{{ hotKeyword }}</div>
|
||||||
<n-spin :show="searchDetailLoading">
|
<n-spin :show="searchDetailLoading">
|
||||||
<div class="search-list-box">
|
<div class="search-list-box">
|
||||||
@@ -59,7 +69,7 @@ import { getHotSearch } from '@/api/home';
|
|||||||
import { getSearch } from '@/api/search';
|
import { getSearch } from '@/api/search';
|
||||||
import SongItem from '@/components/common/SongItem.vue';
|
import SongItem from '@/components/common/SongItem.vue';
|
||||||
import type { IHotSearch } from '@/type/search';
|
import type { IHotSearch } from '@/type/search';
|
||||||
import { setAnimationClass, setAnimationDelay } from '@/utils';
|
import { isMobile, setAnimationClass, setAnimationDelay } from '@/utils';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
@@ -195,4 +205,10 @@ const handlePlay = () => {
|
|||||||
.title {
|
.title {
|
||||||
@apply text-gray-200 text-xl font-bold my-2 mx-4;
|
@apply text-gray-200 text-xl font-bold my-2 mx-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.hot-search {
|
||||||
|
@apply mr-0 w-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import SongItem from '@/components/common/SongItem.vue';
|
|||||||
import MusicList from '@/components/MusicList.vue';
|
import MusicList from '@/components/MusicList.vue';
|
||||||
import type { Playlist } from '@/type/listDetail';
|
import type { Playlist } from '@/type/listDetail';
|
||||||
import type { IUserDetail } from '@/type/user';
|
import type { IUserDetail } from '@/type/user';
|
||||||
import { getImgUrl, setAnimationClass, setAnimationDelay } from '@/utils';
|
import { getImgUrl, isMobile, setAnimationClass, setAnimationDelay } from '@/utils';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'User',
|
name: 'User',
|
||||||
@@ -120,7 +120,7 @@ const handlePlay = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right" :class="setAnimationClass('animate__fadeInRight')">
|
<div v-if="!isMobile" class="right" :class="setAnimationClass('animate__fadeInRight')">
|
||||||
<div class="title">听歌排行</div>
|
<div class="title">听歌排行</div>
|
||||||
<div class="record-list">
|
<div class="record-list">
|
||||||
<n-scrollbar>
|
<n-scrollbar>
|
||||||
@@ -217,4 +217,10 @@ const handlePlay = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.user-page {
|
||||||
|
@apply px-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user