♻️ itemBox 组件重构,更加自由

This commit is contained in:
BTMuli
2023-06-02 17:43:10 +08:00
parent bb2fe8cf46
commit 50b1f16f7f
7 changed files with 161 additions and 144 deletions

View File

@@ -1,30 +1,32 @@
<template>
<TItemBox :data="character as Record<string,string|number>" size="70px" display="inner" model-value="abyss-detail" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
// vue
import { onMounted, ref } from "vue";
import TItemBox from "../main/t-itembox.vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
// utils
import TGSqlite from "../../plugins/Sqlite";
interface TibAbyssDetailProps {
modelValue: TGApp.Sqlite.Abyss.CharacterInfo
}
export interface TibAbyssDetailAvatar extends TGApp.Sqlite.Character.AppData {
value: number,
modelValue: TGApp.Sqlite.Abyss.CharacterInfo;
}
const props = defineProps<TibAbyssDetailProps>();
const character = ref({} as TibAbyssDetailAvatar);
const box = ref({} as TItemBoxData);
onMounted(async () => {
const res = await TGSqlite.getAppCharacter(props.modelValue.id);
character.value = {
...res,
value: props.modelValue.level,
} as TibAbyssDetailAvatar;
box.value = {
height: "70px",
ltSize: "25px",
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
icon: `/WIKI/character/icon/${props.modelValue.id}.webp`,
lt: `/icon/element/${res.element}元素.webp`,
innerText: `Lv.${props.modelValue.level}`,
innerHeight: 20,
display: "inner",
size: "70px",
};
});
</script>

View File

@@ -1,10 +1,10 @@
<template>
<TItemBox :data="character as Record<string,string|number>" size="80px" model-value="abyss-overview" display="inner" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
// vue
import { onMounted, ref } from "vue";
import TItemBox from "../main/t-itembox.vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
// utils
import TGSqlite from "../../plugins/Sqlite";
@@ -12,19 +12,21 @@ interface TibAbyssOverviewProps {
modelValue: TGApp.Sqlite.Abyss.Character;
}
export interface TibAbyssOverviewAvatar extends TGApp.Sqlite.Character.AppData {
value: number,
}
const props = defineProps<TibAbyssOverviewProps>();
const character = ref({} as TibAbyssOverviewAvatar);
const box = ref({} as TItemBoxData);
onMounted(async () => {
const res = await TGSqlite.getAppCharacter(props.modelValue.id);
character.value = {
...res,
value: props.modelValue.value,
} as TibAbyssOverviewAvatar;
box.value = {
height: "80px",
ltSize: "30px",
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
icon: `/WIKI/character/icon/${props.modelValue.id}.webp`,
lt: `/icon/element/${res.element}元素.webp`,
innerText: props.modelValue.value.toString(),
display: "inner",
size: "80px",
innerHeight: 20,
};
});
</script>

View File

@@ -1,13 +1,28 @@
<template>
<TItemBox :data="props.modelValue as Record<string,string|number>" :size="props.size" model-value="calendar-avatar" display="inner" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
import TItemBox from "../main/t-itembox.vue";
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarAvatarProps {
size: string,
modelValue: TGApp.App.Calendar.Item
}
const props = defineProps<TibCalendarAvatarProps>();
const box = computed(() => {
return {
bg: props.modelValue.bg,
icon: props.modelValue.icon,
size: "100px",
height: "100px",
display: "inner",
lt: props.modelValue.elementIcon,
ltSize: "30px",
innerHeight: 25,
innerIcon: props.modelValue.weaponIcon,
innerText: props.modelValue.name,
} as TItemBoxData;
});
</script>

View File

@@ -1,13 +1,27 @@
<template>
<TItemBox :data="props.modelValue as Record<string,string|number>" :size="props.size" model-value="calendar-weapon" display="inner" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
import TItemBox from "../main/t-itembox.vue";
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarWeaponProps {
size: string,
modelValue: TGApp.App.Calendar.Item
modelValue: TGApp.App.Calendar.Item;
}
const props = defineProps<TibCalendarWeaponProps>();
const box = computed(() => {
return {
bg: props.modelValue.bg,
icon: props.modelValue.icon,
size: "100px",
height: "100px",
display: "inner",
lt: props.modelValue.weaponIcon,
ltSize: "30px",
innerHeight: 25,
innerText: props.modelValue.name,
} as TItemBoxData;
});
</script>

View File

@@ -1,13 +1,28 @@
<template>
<TItemBox :data="props.modelValue as Record<string,string|number>" :size="props.size" model-value="wiki-avatar" display="inner" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
import TItemBox from "../main/t-itembox.vue";
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarAvatarProps {
size: string,
modelValue: TGApp.App.Character.WikiBriefInfo
modelValue: TGApp.App.Character.WikiBriefInfo;
}
const props = defineProps<TibCalendarAvatarProps>();
const box = computed(() => {
return {
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
icon: `/WIKI/character/icon/${props.modelValue.id}.webp`,
size: "128px",
height: "128px",
display: "inner",
lt: `/icon/element/${props.modelValue.element}元素.webp`,
ltSize: "40px",
innerHeight: 30,
innerIcon: `/icon/weapon/${props.modelValue.weapon}.webp`,
innerText: props.modelValue.name,
} as TItemBoxData;
});
</script>

View File

@@ -1,13 +1,27 @@
<template>
<TItemBox :data="props.modelValue as Record<string,string|number>" :size="props.size" model-value="wiki-weapon" display="inner" />
<TItemBox :model-value="box" />
</template>
<script lang="ts" setup>
import TItemBox from "../main/t-itembox.vue";
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarWeaponProps {
size: string,
modelValue: TGApp.App.Weapon.WikiBriefInfo
}
const props = defineProps<TibCalendarWeaponProps>();
const box = computed(() => {
return {
bg: props.modelValue.bg,
icon: props.modelValue.icon,
size: "128px",
height: "128px",
display: "inner",
lt: props.modelValue.weaponIcon,
ltSize: "40px",
innerText: props.modelValue.name,
innerHeight: 30,
} as TItemBoxData;
});
</script>

View File

@@ -2,133 +2,87 @@
<div class="tib-box">
<div class="tib-bg">
<slot name="bg">
<img :src="card.bg" alt="bg">
<img :src="modelValue.bg" alt="bg">
</slot>
</div>
<div class="tib-icon">
<slot name="icon">
<img :src="card.icon" alt="icon">
<img :src="modelValue.icon" alt="icon">
</slot>
</div>
<div class="tib-cover">
<div class="tib-lt">
<img :src="card.lt" alt="lt">
<img :src="modelValue.lt" alt="lt">
</div>
<div v-show="card.rt" class="tib-rt">
{{ card.rt }}
<div v-show="modelValue.rt" class="tib-rt">
{{ modelValue.rt }}
</div>
<div v-show="props.display==='inner'" class="tib-inner">
<div v-if="modelValue.display==='inner'" class="tib-inner">
<slot name="inner-icon">
<img v-show="card.innerIcon" :src="card.innerIcon" alt="inner-icon">
<img v-show="modelValue.innerIcon" :src="modelValue.innerIcon" alt="inner-icon">
</slot>
<slot name="inner-text">
<span>{{ card.innerText }}</span>
<span>{{ modelValue.innerText }}</span>
</slot>
</div>
<div v-show="props.display==='outer'" class="tib-outer">
<div v-if="modelValue.display==='outer'" class="tib-outer">
<slot name="outer-icon">
<img v-show="card.outerIcon" :src="card.outerIcon" alt="outer-icon">
<img v-show="modelValue.outerIcon" :src="modelValue.outerIcon" alt="outer-icon">
</slot>
<slot name="outer-text">
<span>{{ card.outerText }}</span>
<span>{{ modelValue.outerText }}</span>
</slot>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
// vue
import { computed, ComputedRef } from "vue";
// types
import { TibAbyssOverviewAvatar } from "../itembox/tib-abyss-overview.vue";
import { TibAbyssDetailAvatar } from "../itembox/tib-abyss-detail.vue";
import { computed } from "vue";
interface TItemBoxProps {
modelValue: string
data: Record<string, string | number>,
display: "inner" | "outer",
size: string,
}
interface TItemBoxCard {
export interface TItemBoxData {
bg: string,
icon: string,
size: string,
height: string,
display: "inner" | "outer",
lt: string,
ltSize: string,
rt?: string,
rtSize?: string,
innerHeight?: number,
innerIcon?: string,
innerText?: string,
outerHeight?: number,
outerIcon?: string,
outerText?: string,
}
const props = defineProps<TItemBoxProps>();
interface TItemBoxProps {
modelValue: TItemBoxData,
}
const getHeight = computed(() => {
return props.display === "inner" ? props.size : `${Number(props.size.slice(0, -2)) + 20}px`;
});
const card: ComputedRef<TItemBoxCard> = computed(() => {
let cardData;
switch (props.modelValue) {
case "calendar-avatar":
cardData = props.data as TGApp.App.Calendar.Item;
return {
bg: cardData.bg,
icon: cardData.icon,
lt: cardData.elementIcon,
innerIcon: cardData.weaponIcon,
innerText: cardData.name,
} as TItemBoxCard;
case "calendar-weapon":
cardData = props.data as TGApp.App.Calendar.Item;
return {
bg: cardData.bg,
icon: cardData.icon,
lt: cardData.weaponIcon,
innerText: cardData.name,
} as TItemBoxCard;
case "wiki-avatar":
cardData = props.data as TGApp.App.Character.WikiBriefInfo;
return {
bg: `/icon/bg/${cardData.star}-Star.webp`,
icon: `/WIKI/character/icon/${cardData.id}.webp`,
lt: `/icon/element/${cardData.element}元素.webp`,
innerIcon: `/icon/weapon/${cardData.weapon}.webp`,
innerText: cardData.name,
} as TItemBoxCard;
case "wiki-weapon":
cardData = props.data as TGApp.App.Weapon.WikiBriefInfo;
return {
bg: cardData.bg,
icon: cardData.icon,
lt: cardData.weaponIcon,
innerText: cardData.name,
} as TItemBoxCard;
case "abyss-overview":
cardData = props.data as TibAbyssOverviewAvatar;
return {
bg: `/icon/bg/${cardData.star}-Star.webp`,
icon: `/WIKI/character/icon/${cardData.id}.webp`,
lt: `/icon/element/${cardData.element}元素.webp`,
innerText: cardData.value,
} as TItemBoxCard;
case "abyss-detail":
cardData = props.data as TibAbyssDetailAvatar;
return {
bg: `/icon/bg/${cardData.star}-Star.webp`,
icon: `/WIKI/character/icon/${cardData.id}.webp`,
lt: `/icon/element/${cardData.element}元素.webp`,
innerText: `Lv.${cardData.value}`,
} as TItemBoxCard;
}
const props = withDefaults(defineProps<TItemBoxProps>(), {
modelValue: {
bg: "",
icon: "",
lt: "",
ltSize: "30px",
display: "inner",
size: "80px",
height: "80px",
},
});
const getInnerHeight = computed(() => `${props.modelValue.innerHeight}px`);
const getInnerFont = computed(() => `${props.modelValue.innerHeight / 2}px`);
const getOuterHeight = computed(() => `${props.modelValue.outerHeight}px`);
const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
</script>
<style lang="css" scoped>
.tib-box {
position: relative;
width: v-bind(size);
height: v-bind(getHeight);
width: v-bind(props["modelValue"]["size"]);
height: v-bind(props["modelValue"]["height"]);
cursor: pointer;
}
@@ -136,29 +90,29 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
width: v-bind(props["modelValue"]["size"]);
height: v-bind(props["modelValue"]["size"]);
border-radius: 5px;
overflow: hidden;
}
.tib-bg img {
width: v-bind(size);
height: v-bind(size);
width: 100%;
height: 100%;
object-fit: cover;
}
.tib-icon {
position: relative;
width: 100%;
height: 100%;
width: v-bind(props["modelValue"]["size"]);
height: v-bind(props["modelValue"]["size"]);
overflow: hidden;
border-radius: 5px;
}
.tib-icon img {
width: v-bind(size);
height: v-bind(size);
width: 100%;
height: 100%;
object-fit: cover;
}
@@ -166,8 +120,8 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
width: v-bind(props["modelValue"]["size"]);
height: v-bind(props["modelValue"]["size"]);
border-radius: 5px;
display: flex;
justify-content: center;
@@ -179,16 +133,17 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
padding: 5px;
width: v-bind(props["modelValue"]["ltSize"]);
height: v-bind(props["modelValue"]["ltSize"]);
display: flex;
justify-content: center;
align-items: center;
}
.tib-lt img {
width: 20px;
height: 20px;
width: 100%;
height: 100%;
object-fit: cover;
}
@@ -197,7 +152,7 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
bottom: 0;
left: 0;
width: 100%;
height: 20px;
height: v-bind(getInnerHeight);
display: flex;
justify-content: center;
align-items: center;
@@ -205,14 +160,14 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
color: #fff;
font-size: 8px;
font-size: v-bind(getInnerFont);
text-shadow: 0 0 5px #000;
font-family: Genshin, serif;
}
.tib-inner img {
width: 20px;
height: 20px;
width: v-bind(getInnerHeight);
height: v-bind(getInnerHeight);
margin-right: 5px;
}
@@ -222,14 +177,14 @@ const card: ComputedRef<TItemBoxCard> = computed(() => {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
width: 100%;
height: 20px;
height: v-bind(getOuterHeight);
background: rgb(0 0 0/ 20%);
display: flex;
justify-content: center;
align-items: center;
font-family: Genshin, serif;
color: #fff;
font-size: 8px;
font-size: v-bind(getOuterFont);
text-shadow: 0 0 5px #000;
}
</style>