♻️ 优化素材日历组件

This commit is contained in:
BTMuli
2023-06-26 17:00:44 +08:00
parent 05df2c0589
commit 0c923060b8
6 changed files with 139 additions and 175 deletions

View File

@@ -1,28 +0,0 @@
<template>
<TItemBox :model-value="box" style="cursor: pointer" />
</template>
<script lang="ts" setup>
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarAvatarProps {
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

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

View File

@@ -1,27 +0,0 @@
<template>
<TItemBox :model-value="box" style="cursor: pointer" />
</template>
<script lang="ts" setup>
// vue
import { computed } from "vue";
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
interface TibCalendarWeaponProps {
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

@@ -12,8 +12,7 @@
:key="text.week"
class="calendar-title-btn"
:style="{
boxShadow: text.week === weekNow ? '0 0 5px #FEC90B' : 'none',
background: text.week === btnNow ? 'rgba(0,0,0,0.8)' : 'rgba(0,0,0,0.3)',
border: btnNow === text.week ? '2px solid var(--common-color-yellow)' : 'none',
}"
@click="getContents(text.week)"
>
@@ -21,31 +20,24 @@
</v-btn>
</div>
</div>
<div class="calendar-divider" />
<div class="calendar-sub">
<TSubLine>角色突破</TSubLine>
<div class="cards-grid">
<div
v-for="item in characterCards"
:key="item.id"
class="card-box"
@click="selectContent(item, 'character')"
>
<TibCalendarAvatar size="100px" :model-value="item" />
</div>
<TSubLine>角色突破</TSubLine>
<div class="calendar-grid">
<div v-for="item in characterCards" :key="item.id" @click="selectAvatar(item)">
<TibCalendarItem
:data="<TGApp.App.Calendar.Item>item"
:model="'avatar'"
:clickable="true"
/>
</div>
</div>
<div class="calendar-sub">
<TSubLine>武器突破</TSubLine>
<div class="cards-grid">
<div
v-for="item in weaponCards"
:key="item.id"
class="card-box"
@click="selectContent(item, 'weapon')"
>
<TibCalendarWeapon size="100px" :model-value="item" />
</div>
<TSubLine>武器突破</TSubLine>
<div class="calendar-grid">
<div v-for="item in weaponCards" :key="item.id" @click="selectWeapon(item)">
<TibCalendarItem
:data="<TGApp.App.Calendar.Item>item"
:model="'weapon'"
:clickable="true"
/>
</div>
</div>
<ToCalendar v-model="showItem" :data-type="selectedType" :data-val="selectedItem" />
@@ -56,29 +48,28 @@
import { computed, onMounted, ref } from "vue";
import TSubLine from "./t-subline.vue";
import ToCalendar from "../overlay/to-calendar.vue";
import TibCalendarAvatar from "../itembox/tib-calendar-avatar.vue";
import TibCalendarWeapon from "../itembox/tib-calendar-weapon.vue";
import TibCalendarItem from "../itembox/tib-calendar-item.vue";
// data
import { AppCalendarData } from "../../data";
// loading
const loading = ref(true as boolean);
const loading = ref<boolean>(true);
// data
const calendarData = computed(() => AppCalendarData);
const weekNow = ref(0 as number);
const btnNow = ref(0 as number);
const dateNow = ref(new Date().toLocaleDateString());
const calendarData = computed<TGApp.App.Calendar.Item[]>(() => AppCalendarData);
const weekNow = ref<number>(0);
const btnNow = ref<number>(0);
const dateNow = ref<string>("");
// calendar
const calendarNow = ref([] as TGApp.App.Calendar.Item[]);
const characterCards = ref([] as TGApp.App.Calendar.Item[]);
const weaponCards = ref([] as TGApp.App.Calendar.Item[]);
const calendarNow = ref<TGApp.App.Calendar.Item[]>([]);
const characterCards = ref<TGApp.App.Calendar.Item[]>([]);
const weaponCards = ref<TGApp.App.Calendar.Item[]>([]);
// calendar item
const showItem = ref(false as boolean);
const selectedItem = ref({} as TGApp.App.Calendar.Item);
const selectedType = ref("character");
const showItem = ref<boolean>(false);
const selectedItem = ref<TGApp.App.Calendar.Item>({} as TGApp.App.Calendar.Item);
const selectedType = ref<"avatar" | "weapon">("avatar");
const btnText = [
{
@@ -110,6 +101,7 @@ const btnText = [
text: "周六",
},
];
// expose
defineExpose({
name: "素材日历",
@@ -118,6 +110,13 @@ defineExpose({
onMounted(() => {
const dayNow = new Date().getDay() === 0 ? 7 : new Date().getDay();
dateNow.value = new Date()
.toLocaleDateString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
})
.replace(/\//g, "-");
weekNow.value = dayNow;
btnNow.value = dayNow;
calendarNow.value = getCalendar(dayNow);
@@ -127,17 +126,23 @@ onMounted(() => {
});
// 获取当前日历
function getCalendar(day: number) {
function getCalendar(day: number): TGApp.App.Calendar.Item[] {
return calendarData.value.filter((item) => item.dropDays.includes(day));
}
function selectContent(item: TGApp.App.Calendar.Item, type: string) {
function selectAvatar(item: TGApp.App.Calendar.Item): void {
selectedItem.value = item;
selectedType.value = type;
selectedType.value = "avatar";
showItem.value = true;
}
function getContents(day: number) {
function selectWeapon(item: TGApp.App.Calendar.Item): void {
selectedItem.value = item;
selectedType.value = "weapon";
showItem.value = true;
}
function getContents(day: number): void {
btnNow.value = day;
calendarNow.value = getCalendar(day);
characterCards.value = calendarNow.value.filter((item) => item.itemType === "character");
@@ -148,56 +153,45 @@ function getContents(day: number) {
.calendar-box {
margin-bottom: 10px;
padding: 10px;
background: rgb(255 255 255 / 10%);
box-shadow: 0 0 10px rgb(0 0 0 / 40%);
box-shadow: 0 0 10px var(--common-shadow-4);
border-radius: 5px;
}
.calendar-title {
height: 45px;
color: var(--common-text-title);
font-family: var(--font-title);
font-size: 20px;
display: flex;
color: rgb(255 255 255 / 80%);
align-items: center;
justify-content: start;
column-gap: 2rem;
padding-bottom: 5px;
border-bottom: 2px solid var(--common-shadow-4);
}
.calendar-title-left {
width: 20%;
height: 45px;
font-family: Genshin, serif;
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
display: flex;
align-items: center;
}
.calendar-title-left span {
margin-left: 10px;
justify-content: start;
column-gap: 10px;
}
.calendar-title-right {
width: 80%;
font-family: Genshin-Light, serif;
height: 45px;
display: flex;
align-items: center;
justify-content: start;
column-gap: 15px;
}
.calendar-title-btn {
margin-left: 10px;
background: var(--common-bg-1);
color: var(--common-bgt-1);
border-radius: 5px;
}
.calendar-divider {
width: 100%;
height: 2px;
border-radius: 2px;
background: rgb(0 0 0 / 40%);
}
.calendar-sub {
margin: 5px;
}
.cards-grid {
.calendar-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-gap: 8px;
grid-gap: 10px;
}
</style>

View File

@@ -42,6 +42,7 @@ export interface TItemBoxData {
size: string;
height: string;
display: "inner" | "outer";
clickable: boolean;
lt: string;
ltSize: string;
rt?: string;
@@ -57,19 +58,9 @@ interface TItemBoxProps {
modelValue: TItemBoxData;
}
const props = withDefaults(defineProps<TItemBoxProps>(), {
modelValue: {
bg: "",
icon: "",
lt: "",
ltSize: "30px",
display: "inner",
innerText: "",
size: "80px",
height: "80px",
},
});
const props = defineProps<TItemBoxProps>();
const getCursor = computed(() => (props.modelValue.clickable ? "pointer" : "default"));
const getInnerHeight = computed(() => `${props.modelValue.innerHeight}px`);
const getInnerFont = computed(() => `${props.modelValue.innerHeight / 2}px`);
const getOuterHeight = computed(() => `${props.modelValue.outerHeight}px`);
@@ -78,16 +69,17 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
<style lang="css" scoped>
.tib-box {
position: relative;
width: v-bind(props[ "modelValue"][ "size"]);
height: v-bind(props[ "modelValue"][ "height"]);
width: v-bind(modelValue[ "size"]);
height: v-bind(modelValue[ "height"]);
cursor: v-bind(getCursor);
}
.tib-bg {
position: absolute;
top: 0;
left: 0;
width: v-bind(props[ "modelValue"][ "size"]);
height: v-bind(props[ "modelValue"][ "size"]);
width: v-bind(modelValue[ "size"]);
height: v-bind(modelValue[ "size"]);
border-radius: 5px;
overflow: hidden;
}
@@ -100,8 +92,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
.tib-icon {
position: relative;
width: v-bind(props[ "modelValue"][ "size"]);
height: v-bind(props[ "modelValue"][ "size"]);
width: v-bind(modelValue[ "size"]);
height: v-bind(modelValue[ "size"]);
overflow: hidden;
border-radius: 5px;
}
@@ -116,8 +108,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
position: absolute;
top: 0;
left: 0;
width: v-bind(props[ "modelValue"][ "size"]);
height: v-bind(props[ "modelValue"][ "size"]);
width: v-bind(modelValue[ "size"]);
height: v-bind(modelValue[ "size"]);
border-radius: 5px;
display: flex;
justify-content: center;
@@ -130,8 +122,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
top: 0;
left: 0;
padding: 5px;
width: v-bind(props[ "modelValue"][ "ltSize"]);
height: v-bind(props[ "modelValue"][ "ltSize"]);
width: v-bind(modelValue[ "ltSize"]);
height: v-bind(modelValue[ "ltSize"]);
display: flex;
justify-content: center;
align-items: center;
@@ -147,8 +139,8 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
position: absolute;
top: 0;
right: 0;
width: v-bind(props[ "modelValue"][ "rtSize"]);
height: v-bind(props[ "modelValue"][ "rtSize"]);
width: v-bind(modelValue[ "rtSize"]);
height: v-bind(modelValue[ "rtSize"]);
background: rgb(0 0 0 / 40%);
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;

View File

@@ -3,18 +3,11 @@
<div class="toc-box">
<div class="box-div">
<div class="toc-top">
<div class="toc-icon">
<TibCalendarAvatar
v-if="itemType === 'character'"
v-model="itemVal"
size="100px"
style="cursor: default"
/>
<TibCalendarWeapon
v-if="itemType === 'weapon'"
v-model="itemVal"
size="100px"
style="cursor: default"
<div class="toc-icon" style="cursor: default">
<TibCalendarItem
:model="itemType"
:data="<TGApp.App.Calendar.Item>itemVal"
:clickable="false"
/>
</div>
<div class="toc-material-grid">
@@ -51,37 +44,32 @@
// vue
import { computed, ref } from "vue";
import TOverlay from "../main/t-overlay.vue";
import TibCalendarWeapon from "../itembox/tib-calendar-weapon.vue";
import TibCalendarAvatar from "../itembox/tib-calendar-avatar.vue";
import TibCalendarItem from "../itembox/tib-calendar-item.vue";
import TibCalendarMaterial from "../itembox/tib-calendar-material.vue";
// utils
import { OBC_CONTENT_API } from "../../plugins/Mys/interface/utils";
import { createTGWindow } from "../../utils/TGWindow";
interface TOCalendarProps {
interface ToCalendarProps {
modelValue: boolean;
dataType: string;
dataType: "weapon" | "avatar";
dataVal: TGApp.App.Calendar.Item;
}
interface TOCalendarEmits {
(e: "update:modelValue", value: TGApp.App.Calendar.Item): void;
interface ToCalendarEmits {
(e: "update:modelValue", value: boolean): void;
(e: "cancel"): void;
}
const emits = defineEmits<TOCalendarEmits>();
const props = withDefaults(defineProps<TOCalendarProps>(), {
modelValue: false,
dataType: "",
dataVal: {} as TGApp.App.Calendar.Item,
});
const emits = defineEmits<ToCalendarEmits>();
const props = defineProps<ToCalendarProps>();
const visible = computed({
get: () => props.modelValue,
set: (value) => emits("update:modelValue", value),
});
const itemType = computed(() => props.dataType);
const itemVal = computed(() => props.dataVal);
const itemVal = computed<TGApp.App.Calendar.Item>(() => props.dataVal);
const snackbar = ref(false);
const onCancel = () => {