feat: 优化移动端适配

This commit is contained in:
alger
2026-02-04 21:54:28 +08:00
parent feb041f5c2
commit fab29e5c79
5 changed files with 27 additions and 18 deletions

View File

@@ -38,6 +38,7 @@
:title="album.name"
:subtitle="getArtistNames(album)"
:tracks="albumTracksMap[album.id] || []"
:show-hover-tracks="!isMobile"
:animation-delay="calculateAnimationDelay(index, 0.04)"
@click="handleAlbumClick(album)"
@play="playAlbum(album)"
@@ -62,7 +63,7 @@ import { getAlbum } from '@/api/list';
import { navigateToMusicList } from '@/components/common/MusicListNavigator';
import { usePlayerCoreStore } from '@/store/modules/playerCore';
import { usePlaylistStore } from '@/store/modules/playlist';
import { calculateAnimationDelay, isElectron } from '@/utils';
import { calculateAnimationDelay, isElectron, isMobile } from '@/utils';
import HomeListItem from './HomeListItem.vue';
@@ -104,7 +105,7 @@ const fetchAlbums = async () => {
if (data.code === 200) {
albums.value = data.weekData || data.monthData || data.albums || [];
// Preload tracks for displayed albums (Electron only)
if (isElectron) {
if (isElectron && !isMobile.value) {
preloadAllTracks();
}
}

View File

@@ -68,7 +68,7 @@ import { onMounted, ref } from 'vue';
import { getHotSinger } from '@/api/home';
import { useArtist } from '@/hooks/useArtist';
import { calculateAnimationDelay, getImgUrl } from '@/utils';
import { calculateAnimationDelay, getImgUrl, isMobile } from '@/utils';
const props = defineProps<{
title: string;
@@ -100,6 +100,7 @@ const fetchArtists = async () => {
// Enhanced horizontal scroll with wheel support
const handleWheel = (e: WheelEvent) => {
if (isMobile.value) return;
if (!scrollContainer.value) return;
// Prevent default vertical scroll
@@ -161,7 +162,7 @@ onMounted(() => {
-webkit-overflow-scrolling: touch;
/* Optimize for touch */
touch-action: pan-x;
touch-action: pan-x pan-y;
}
.artists-track {

View File

@@ -16,6 +16,7 @@
<!-- Hover Overlay with Song Preview -->
<div
v-if="showHoverTracks"
class="absolute inset-0 flex items-end opacity-0 transition-all duration-500 ease-out group-hover:opacity-100"
:style="overlayStyle"
>
@@ -108,10 +109,12 @@ const props = withDefaults(
badgeType?: 'new' | 'hot' | 'recommend';
playCount?: number;
animationDelay?: string;
showHoverTracks?: boolean;
}>(),
{
tracks: () => [],
animationDelay: '0s'
animationDelay: '0s',
showHoverTracks: true
}
);

View File

@@ -18,10 +18,7 @@
</div>
<!-- Loading Skeleton -->
<div
v-if="loading"
class="songs-grid grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
>
<div v-if="loading" class="songs-grid grid gap-3" :class="gridClass">
<div
v-for="i in 10"
:key="i"
@@ -30,10 +27,7 @@
</div>
<!-- Songs Grid (Even columns: 12345) -->
<div
v-else
class="songs-grid grid grid-cols-1 gap-2 md:gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
>
<div v-else class="songs-grid grid gap-2 md:gap-3" :class="gridClass">
<song-item
v-for="(song, index) in songs"
:key="song.id"
@@ -49,14 +43,14 @@
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { getRecommendMusic } from '@/api/home';
import SongItem from '@/components/common/SongItem.vue';
import { usePlayerStore } from '@/store';
import { SongResult } from '@/types/music';
import { calculateAnimationDelay } from '@/utils';
import { calculateAnimationDelay, isMobile } from '@/utils';
const props = defineProps<{
title: string;
@@ -67,6 +61,11 @@ const { t } = useI18n();
const playerStore = usePlayerStore();
const songs = ref<SongResult[]>([]);
const loading = ref(true);
const gridClass = computed(() =>
isMobile.value
? 'grid-cols-1 sm:grid-cols-2'
: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'
);
const fetchSongs = async () => {
try {

View File

@@ -60,7 +60,7 @@ import { getListDetail } from '@/api/list';
import { navigateToMusicList } from '@/components/common/MusicListNavigator';
import { usePlayerCoreStore } from '@/store/modules/playerCore';
import { usePlaylistStore } from '@/store/modules/playlist';
import { calculateAnimationDelay, isElectron } from '@/utils';
import { calculateAnimationDelay, isElectron, isMobile } from '@/utils';
import HomeListItem from './HomeListItem.vue';
@@ -88,8 +88,13 @@ const playlists = ref<any[]>([]);
const loading = ref(true);
const playlistTracksMap = reactive<Record<number, any[]>>({});
const effectiveColumns = computed(() =>
isMobile.value ? Math.min(2, props.columns) : props.columns
);
const effectiveRows = computed(() => (isMobile.value ? 2 : props.rows));
// Calculate display count to fill exactly N rows
const displayCount = computed(() => props.columns * props.rows);
const displayCount = computed(() => effectiveColumns.value * effectiveRows.value);
const displayPlaylists = computed(() => {
const count = displayCount.value;
@@ -97,7 +102,7 @@ const displayPlaylists = computed(() => {
});
const gridStyle = computed(() => ({
gridTemplateColumns: `repeat(${props.columns}, minmax(0, 1fr))`
gridTemplateColumns: `repeat(${effectiveColumns.value}, minmax(0, 1fr))`
}));
const fetchPlaylists = async () => {