fix safari card style

This commit is contained in:
jxxghp
2023-06-30 12:50:39 +08:00
parent 2a97fd54a9
commit 27259d5862
9 changed files with 110 additions and 111 deletions
+1 -1
View File
@@ -24,7 +24,7 @@
}, },
// Vue // Vue
"[vue]": { "[vue]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint", "editor.defaultFormatter": "Wscats.vue",
}, },
// Extension: Volar // Extension: Volar
"volar.preview.port": 3000, "volar.preview.port": 3000,
+1
View File
@@ -54,6 +54,7 @@
"@iconify/tools": "^2.2.0", "@iconify/tools": "^2.2.0",
"@iconify/vue": "4.1.1", "@iconify/vue": "4.1.1",
"@intlify/unplugin-vue-i18n": "^0.10.0", "@intlify/unplugin-vue-i18n": "^0.10.0",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@types/node": "^20.1.4", "@types/node": "^20.1.4",
"@types/webfontloader": "^1.6.34", "@types/webfontloader": "^1.6.34",
"@typescript-eslint/eslint-plugin": "^5.59.5", "@typescript-eslint/eslint-plugin": "^5.59.5",
+73 -56
View File
@@ -3,7 +3,9 @@ import { MediaInfo } from "@/api/types";
// 输入参数 // 输入参数
const props = defineProps({ const props = defineProps({
media: Object as PropType<MediaInfo> media: Object as PropType<MediaInfo>,
width: String,
height: String,
}); });
// 图片加载状态 // 图片加载状态
@@ -18,71 +20,86 @@ const getChipColor = (type: string) => {
return "border-purple-600 bg-purple-600"; return "border-purple-600 bg-purple-600";
} }
}; };
</script> </script>
<template> <template>
<VHover v-bind="props"> <VHover v-bind="props">
<template #default="hover" > <template #default="hover">
<VCard <VCard
v-bind="hover.props" v-bind="hover.props"
class="outline-none shadow ring-gray-500" :height="props.height"
:class="{ 'scale-105 shadow-lg': hover.isHovering, 'ring-1 transition duration-300 ': isImageLoaded }" :width="props.width"
> class="outline-none shadow ring-gray-500"
<VImg :class="{
aspect-ratio="3/2" 'scale-105 shadow-lg': hover.isHovering,
:src="props.media?.poster_path" 'ring-1 transition duration-300 ': isImageLoaded,
class="h-full w-full object-cover" }"
:class="hover.isHovering ? 'on-hover' : ''"
cover
@load="isImageLoaded = true"
> >
<template #placeholder> <VImg
<div class="relative animate-pulse bg-gray-300 w-full"><div class="w-full" style="padding-bottom: 150%;"></div></div> aspect-ratio="2/3"
</template> :src="props.media?.poster_path"
<!-- 类型角标 --> class="object-cover aspect-w-2 aspect-h-3"
<VChip :class="hover.isHovering ? 'on-hover' : ''"
variant="elevated" @load="isImageLoaded = true"
size="small" cover
:class="getChipColor(props.media?.type||'')"
class="absolute left-2 top-2 bg-opacity-80 shadow-md text-white font-bold">
{{ props.media?.type }}
</VChip>
<!-- 评分角标 -->
<VChip
variant="elevated"
size="small"
v-if="props.media?.vote_average"
:class="getChipColor('')"
class="absolute right-2 top-2 bg-opacity-80 shadow-md text-white font-bold">
{{ props.media?.vote_average }}
</VChip>
<!-- 详情 -->
<VCardText
class="flex flex-col flex-wrap justify-end align-left text-white absolute bottom-0 cursor-pointer pa-2"
v-show="hover.isHovering"
> >
<span class="font-bold">{{ props.media?.year }}</span> <template #placeholder>
<h1 class="mb-1 text-white font-extrabold text-xl line-clamp-2 overflow-hidden text-ellipsis ..."> <div class="relative animate-pulse bg-gray-300 w-full">
{{ props.media?.title }} <div class="w-full h-full"></div>
</h1> </div>
<p class="leading-4 line-clamp-4 overflow-hidden text-ellipsis ..."> </template>
{{ props.media?.overview }} <!-- 类型角标 -->
</p> <VChip
<div class="flex align-center justify-between"> variant="elevated"
<IconBtn icon="mdi-magnify" color="white" size="small"
/> :class="getChipColor(props.media?.type || '')"
<IconBtn icon="mdi-heart" color="white" /> class="absolute left-2 top-2 bg-opacity-80 shadow-md text-white font-bold"
</div> >
</VCardText> {{ props.media?.type }}
</VImg> </VChip>
</VCard> <!-- 评分角标 -->
</template> <VChip
</VHover> variant="elevated"
size="small"
v-if="props.media?.vote_average"
:class="getChipColor('')"
class="absolute right-2 top-2 bg-opacity-80 shadow-md text-white font-bold"
>
{{ props.media?.vote_average }}
</VChip>
<!-- 详情 -->
<VCardText
class="flex flex-col flex-wrap justify-end align-left text-white absolute bottom-0 cursor-pointer pa-2"
v-show="hover.isHovering"
>
<span class="font-bold">{{ props.media?.year }}</span>
<h1
class="mb-1 text-white font-extrabold text-xl line-clamp-2 overflow-hidden text-ellipsis ..."
>
{{ props.media?.title }}
</h1>
<p class="leading-4 line-clamp-4 overflow-hidden text-ellipsis ...">
{{ props.media?.overview }}
</p>
<div class="flex align-center justify-between">
<IconBtn icon="mdi-magnify" color="white" />
<IconBtn icon="mdi-heart" color="white" />
</div>
</VCardText>
</VImg>
</VCard>
</template>
</VHover>
</template> </template>
<style type="scss"> <style type="scss">
.on-hover img { .on-hover img {
@apply brightness-50; @apply brightness-50;
} }
.media-slide-card {
position: relative;
flex: 0 0 auto;
max-inline-size: 11rem;
}
</style> </style>
-14
View File
@@ -2,17 +2,3 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
.grid-media-card {
grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr));
}
.media-slide-card {
position: relative;
flex: 0 0 auto;
max-width: 11rem;
}
.grid-subscribe-card {
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}
+10 -10
View File
@@ -8,8 +8,6 @@ const props = defineProps({
apipath: String, apipath: String,
}); });
console.log(props.apipath)
// 当前页码 // 当前页码
const page = ref(1); const page = ref(1);
// 是否加载中 // 是否加载中
@@ -22,8 +20,8 @@ const currData = ref<MediaInfo[]>([]);
// 获取订阅列表数据 // 获取订阅列表数据
const fetchData = async ({ done }) => { const fetchData = async ({ done }) => {
try { try {
if (!props.apipath){ if (!props.apipath) {
return return;
} }
// 如果正在加载中,直接返回 // 如果正在加载中,直接返回
if (loading.value) { if (loading.value) {
@@ -45,10 +43,9 @@ const fetchData = async ({ done }) => {
} finally { } finally {
// 取消加载中 // 取消加载中
loading.value = false; loading.value = false;
done('ok') done("ok");
} }
}; };
</script> </script>
<template> <template>
@@ -60,10 +57,13 @@ const fetchData = async ({ done }) => {
> >
<template #loading /> <template #loading />
<div class="grid gap-4 grid-media-card mx-3"> <div class="grid gap-4 grid-media-card mx-3">
<MediaCard v-for="data in dataList" <MediaCard v-for="data in dataList" :key="data.tmdb_id" :media="data"> </MediaCard>
:key="data.tmdb_id"
:media="data">
</MediaCard>
</div> </div>
</VInfiniteScroll> </VInfiniteScroll>
</template> </template>
<style type="scss">
.grid-media-card {
grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr));
}
</style>
+7 -24
View File
@@ -14,8 +14,8 @@ const dataList = ref<MediaInfo[]>([]);
// 获取订阅列表数据 // 获取订阅列表数据
const fetchData = async () => { const fetchData = async () => {
try { try {
if (!props.apipath){ if (!props.apipath) {
return return;
} }
dataList.value = await api.get(props.apipath); dataList.value = await api.get(props.apipath);
} catch (error) { } catch (error) {
@@ -25,41 +25,24 @@ const fetchData = async () => {
// 加载时获取数据 // 加载时获取数据
onMounted(fetchData); onMounted(fetchData);
</script> </script>
<template> <template>
<VSlideGroup <VSlideGroup show-arrows="false">
show-arrows=false
>
<template #prev> <template #prev>
<VBtn <VBtn class="rounded-circle shadow-none" icon="mdi-chevron-left" color="grey" />
class="rounded-circle shadow-none"
icon="mdi-chevron-left"
color="grey"
/>
</template> </template>
<VSlideGroupItem v-for="data in dataList" <VSlideGroupItem v-for="data in dataList" :key="data.tmdb_id">
:key="data.tmdb_id" <MediaCard :media="data" height="15rem" width="10rem" />
>
<MediaCard
:media="data"
/>
</VSlideGroupItem> </VSlideGroupItem>
<template #next> <template #next>
<VBtn <VBtn class="rounded-circle shadow-none" icon="mdi-chevron-right" color="grey" />
class="rounded-circle shadow-none"
icon="mdi-chevron-right"
color="grey"
/>
</template> </template>
</VSlideGroup> </VSlideGroup>
</template> </template>
<style type="scss"> <style type="scss">
.v-slide-group .v-card { .v-slide-group .v-card {
block-size: 15rem;
@apply m-2; @apply m-2;
} }
+6 -5
View File
@@ -27,15 +27,16 @@ onMounted(fetchData);
const filteredDataList = computed(() => { const filteredDataList = computed(() => {
return dataList.value.filter((data) => data.type === props.type); return dataList.value.filter((data) => data.type === props.type);
}); });
</script> </script>
<template> <template>
<div class="grid gap-3 grid-subscribe-card"> <div class="grid gap-3 grid-subscribe-card">
<SubscribeCard v-for="data in filteredDataList" <SubscribeCard v-for="data in filteredDataList" :key="data.id" :media="data" />
:key="data.id"
:media="data"
/>
</div> </div>
</template> </template>
<style type="scss">
.grid-subscribe-card {
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}
</style>
+7 -1
View File
@@ -4,6 +4,12 @@ module.exports = {
theme: { theme: {
extend: {}, extend: {},
}, },
plugins: [], corePlugins: {
aspectRatio: false,
},
plugins: [
require('@tailwindcss/aspect-ratio'),
// ...
],
} }
+5
View File
@@ -1792,6 +1792,11 @@
magic-string "^0.25.0" magic-string "^0.25.0"
string.prototype.matchall "^4.0.6" string.prototype.matchall "^4.0.6"
"@tailwindcss/aspect-ratio@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz#9ffd52fee8e3c8b20623ff0dcb29e5c21fb0a9ba"
integrity sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==
"@trysound/sax@0.2.0": "@trysound/sax@0.2.0":
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"