👽️ migrate to vuetify4

This commit is contained in:
BTMuli
2026-02-25 19:13:58 +08:00
parent f42e6d4c8a
commit a4b4232671
16 changed files with 819 additions and 1369 deletions

View File

@@ -1,6 +1,6 @@
/**
* 全局样式文件
* @since Beta v0.9.1
* @since Beta v0.9.6
*/
@use "fonts/index";
@@ -57,15 +57,15 @@
--tgi-snackbar: 9999;
}
/*
* @description 根 html 样式
* @since Beta v0.3.0
/**
* 根 html 样式
* @since Beta v0.9.6
*/
html {
overflow: auto;
background: var(--app-page-bg);
font-family: var(--font-text);
font-family: var(--font-text) !important;
font-size: 16px;
}

View File

@@ -9,7 +9,7 @@
/>
<div class="mid-menu">
<!-- 菜单项 -->
<v-list-item :link="true" :title.attr="'首页'" href="/">
<v-list-item :link="true" :title.attr="'首页'" class="thin-spacer" href="/">
<template #title>首页</template>
<template #prepend>
<img alt="homeIcon" class="side-icon paimon" src="/UI/nav/paimon.webp" />
@@ -206,7 +206,7 @@
<!-- 用户菜单 -->
<v-menu :open-on-click="true" location="end">
<template #activator="{ props }">
<v-list-item :title.attr="userInfo.nickname" v-bind="props">
<v-list-item :title.attr="userInfo.nickname" class="thin-spacer" v-bind="props">
<template #title>{{ userInfo.nickname }}</template>
<template #prepend>
<img :src="userInfo.avatar" alt="userIcon" class="side-icon paimon" />
@@ -812,8 +812,10 @@ async function tryLaunchGame(): Promise<void> {
}
}
</script>
<style lang="css" scoped>
<style lang="scss" scoped>
.tsb-box {
--v-list-prepend-gap: 24px;
position: relative;
background: var(--app-side-bg);
color: var(--app-side-content);
@@ -841,8 +843,8 @@ async function tryLaunchGame(): Promise<void> {
width: 100%;
}
:deep(.side-icon.paimon + .v-list-item__spacer) {
width: 24px;
.thin-spacer {
--v-list-prepend-gap: 16px;
}
.side-icon {

View File

@@ -5,7 +5,7 @@
<slot name="left"></slot>
<div class="pbom-box">
<div class="pbom-share">
{{ dbInfo.updated }} | UID {{ props.uid }} | TeyvatGuide v{{ version }}
ID {{ props.data.info.id }} | UID {{ props.uid }} | TeyvatGuide v{{ version }}
</div>
<div class="pbom-top">
<div class="pbom-icon">
@@ -81,7 +81,7 @@ const showRecord = computed<boolean>(() => !SKIP_BAG_TYPES.includes(props.data.i
onMounted(async () => (version.value = await getVersion()));
const dbInfo = shallowRef<TGApp.Sqlite.UserBag.MaterialTable>(props.data.tb);
console.log(dbInfo.value);
watch(
() => props.data.info,
async () => await refreshDb(),

View File

@@ -62,7 +62,7 @@ import { computed } from "vue";
import TuaRelicBox from "./tua-relic-box.vue";
import { AppCharacterData } from "@/data/index.js";
import { AppCalendarData, AppCharacterData } from "@/data/index.js";
type fixedLenArr<T, N extends number> = [T, ...Array<T>] & { length: N };
type AvatarRelics = fixedLenArr<TGApp.Game.Avatar.Relic | false, 5>;
@@ -74,7 +74,9 @@ const userStore = useUserStore();
const avatarIcon = computed<string>(() => {
const costume = getCostume();
if (costume) return `/WIKI/costume/${costume.id}.webp`;
return `/WIKI/character/${props.role.avatar.id}.webp`;
const findA = AppCalendarData.find((a) => a.id === props.role.avatar.id);
if (findA) return `/WIKI/character/${props.role.avatar.id}.webp`;
return props.role.avatar.icon;
});
const avatarBox = computed<TItemBoxData>(() => ({
size: "100px",
@@ -90,20 +92,25 @@ const avatarBox = computed<TItemBoxData>(() => ({
display: "inner",
clickable: true,
}));
const weaponBox = computed<TItemBoxData>(() => ({
size: "65px",
height: "65px",
bg: `/icon/bg/${props.role.weapon.rarity}-Star.webp`,
icon: `/WIKI/weapon/${props.role.weapon.id}.webp`,
lt: `/icon/weapon/${props.role.weapon.type_name}.webp`,
ltSize: "20px",
rt: props.role.weapon.affix_level.toString(),
rtSize: "20px",
innerText: props.role.weapon.name,
innerHeight: 20,
display: "inner",
clickable: true,
}));
const weaponBox = computed<TItemBoxData>(() => {
let icon = props.role.weapon.icon;
const findW = AppCalendarData.find((w) => w.id === props.role.weapon.id);
if (findW) icon = `/WIKI/weapon/${props.role.weapon.id}.webp`;
return {
size: "65px",
height: "65px",
bg: `/icon/bg/${props.role.weapon.rarity}-Star.webp`,
icon: icon,
lt: `/icon/weapon/${props.role.weapon.type_name}.webp`,
ltSize: "20px",
rt: props.role.weapon.affix_level.toString(),
rtSize: "20px",
innerText: props.role.weapon.name,
innerHeight: 20,
display: "inner",
clickable: true,
};
});
const relicsBox = computed<AvatarRelics>(() => {
const relics = props.role.relics;
return [
@@ -146,7 +153,7 @@ function getWeaponTitle(): string {
title.push(`${weapon.rarity}星 精炼${weapon.affix_level} Lv.${weapon.level}`);
const propMain = userStore.getProp(weapon.main_property.property_type);
title.push(`${propMain !== false ? propMain.name : "未知属性"} - ${weapon.main_property.final}`);
if (weapon.sub_property !== null) {
if (weapon.sub_property !== undefined && weapon.sub_property !== null) {
const propSub = userStore.getProp(weapon.sub_property.property_type);
title.push(`${propSub !== false ? propSub.name : "未知属性"} - ${weapon.sub_property.final}`);
}

View File

@@ -1,11 +1,13 @@
/**
* 应用入口
* @since Beta v0.9.2
* @since Beta v0.9.6
*/
import * as Sentry from "@sentry/vue";
import { createApp, defineCustomElement } from "vue";
import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import App from "./App.vue";
import TLink from "./components/web/t-link.vue";
@@ -17,6 +19,8 @@ import "vuetify/styles";
import "./assets/index.scss";
const app = createApp(App);
const vuetify = createVuetify({ components, directives });
customElements.define("t-link", defineCustomElement(TLink));
Sentry.init({
@@ -45,4 +49,4 @@ Sentry.init({
Sentry.setTag("commitHash", import.meta.env.VITE_COMMIT_HASH);
Sentry.setTag("buildTime", import.meta.env.VITE_BUILD_TIME);
app.use(router).use(store).use(createVuetify()).mount("#app");
app.use(router).use(store).use(vuetify).mount("#app");

View File

@@ -18,19 +18,19 @@
>
<template #selection="{ item }">
<div class="select-main">
<img :src="item.raw.brief.avatar" alt="icon" />
<img :src="item.brief.avatar" alt="icon" />
<div class="content">
<span>{{ item.raw.brief.nickname }}</span>
<span>UID:{{ item.raw.uid }}</span>
<span>{{ item.brief.nickname }}</span>
<span>UID:{{ item.uid }}</span>
</div>
</div>
</template>
<template #item="{ props, item }">
<div class="select-item" v-bind="props">
<img :src="item.raw.brief.avatar" alt="icon" />
<img :src="item.brief.avatar" alt="icon" />
<div class="content">
<span>{{ item.raw.brief.nickname }}</span>
<span>UID:{{ item.raw.uid }}</span>
<span>{{ item.brief.nickname }}</span>
<span>UID:{{ item.uid }}</span>
</div>
</div>
</template>

View File

@@ -21,7 +21,7 @@
<template #item="{ props, item }">
<v-list-item v-bind="props">
<template #append>
<v-chip>{{ item.raw.number }}</v-chip>
<v-chip>{{ item.number }}</v-chip>
</template>
</v-list-item>
</template>

View File

@@ -20,7 +20,7 @@
<template #item="{ props, item }">
<v-list-item v-bind="props">
<template #append>
<v-chip>{{ item.raw.number }}</v-chip>
<v-chip>{{ item.number }}</v-chip>
</template>
</v-list-item>
</template>

View File

@@ -64,7 +64,7 @@
<template #item="{ props, item }">
<v-list-item v-bind="props">
<template #append>
<v-chip>{{ item.raw.number }}</v-chip>
<v-chip>{{ item.number }}</v-chip>
</template>
</v-list-item>
</template>

View File

@@ -16,30 +16,30 @@
<template #selection="{ item }">
<div class="select-item main">
<TMiImg
v-if="item.raw.icon"
:alt="item.raw.title"
v-if="item.icon"
:alt="item.title"
:ori="true"
:src="item.raw.icon"
:title="item.raw.title"
:src="item.icon"
:title="item.title"
class="icon"
/>
<span>{{ item.raw.title }}</span>
<span>{{ item.title }}</span>
</div>
</template>
<template #item="{ props, item }">
<div
:class="item.raw.gid === curGid ? 'selected' : ''"
:class="item.gid === curGid ? 'selected' : ''"
class="select-item sub"
v-bind="props"
>
<TMiImg
v-if="item.raw.icon"
:alt="item.raw.title"
:src="item.raw.icon"
:title="item.raw.title"
v-if="item.icon"
:alt="item.title"
:src="item.icon"
:title="item.title"
class="icon"
/>
<span>{{ item.raw.title }}</span>
<span>{{ item.title }}</span>
</div>
</template>
</v-select>

View File

@@ -16,7 +16,7 @@
variant="outlined"
>
<template v-slot:item="{ props, item }">
<v-list-item :subtitle="item.raw.desc" :title="item.raw.title" v-bind="props" />
<v-list-item :subtitle="item.desc" :title="item.title" v-bind="props" />
</template>
</v-select>
</div>

View File

@@ -21,30 +21,20 @@
<template #selection="{ item }">
<div class="select-item main">
<TMiImg
v-if="item.raw.icon"
:alt="item.raw.text"
v-if="item.icon"
:alt="item.text"
:ori="true"
:src="item.raw.icon"
:title="item.raw.text"
:src="item.icon"
:title="item.text"
class="icon"
/>
<span>{{ item.raw.text }}</span>
<span>{{ item.text }}</span>
</div>
</template>
<template #item="{ props, item }">
<div
:class="{ selected: item.raw.gid === curGid }"
class="select-item sub"
v-bind="props"
>
<TMiImg
v-if="item.raw.icon"
:alt="item.raw.text"
:ori="true"
:src="item.raw.icon"
class="icon"
/>
<span>{{ item.raw.text }}</span>
<div :class="{ selected: item.gid === curGid }" class="select-item sub" v-bind="props">
<TMiImg v-if="item.icon" :alt="item.text" :ori="true" :src="item.icon" class="icon" />
<span>{{ item.text }}</span>
</div>
</template>
</v-select>
@@ -59,25 +49,19 @@
>
<template #selection="{ item }">
<div class="select-item main">
<TMiImg
:alt="item.raw.text"
:ori="true"
:src="item.raw.icon"
:title="item.raw.text"
class="icon"
/>
<span>{{ item.raw.text }}</span>
<TMiImg :alt="item.text" :ori="true" :src="item.icon" :title="item.text" class="icon" />
<span>{{ item.text }}</span>
</div>
</template>
<template #item="{ props, item }">
<div
:class="{ selected: item.raw.value === selectedForum?.value }"
:class="{ selected: item.value === selectedForum?.value }"
class="select-item sub"
v-bind="props"
@click="selectedForum = item.raw"
@click="() => (selectedForum = item)"
>
<TMiImg :alt="item.raw.text" :ori="true" :src="item.raw.icon" class="icon" />
<span>{{ item.raw.text }}</span>
<TMiImg :alt="item.text" :ori="true" :src="item.icon" class="icon" />
<span>{{ item.text }}</span>
</div>
</template>
</v-select>

View File

@@ -32,25 +32,25 @@
<template #selection="{ item }">
<div class="select-item main">
<img
v-if="item.raw.icon"
:alt="item.raw.name"
:src="item.raw.icon"
:title="item.raw.name"
v-if="item.icon"
:alt="item.name"
:src="item.icon"
:title="item.name"
class="icon"
/>
<span>{{ item.raw.name }}</span>
<span>{{ item.name }}</span>
</div>
</template>
<template #item="{ props, item }">
<div :class="{ selected: item.raw.id === curGid }" class="select-item sub" v-bind="props">
<div :class="{ selected: item.id === curGid }" class="select-item sub" v-bind="props">
<img
v-if="item.raw.icon"
:alt="item.raw.name"
:src="item.raw.icon"
:title="item.raw.name"
v-if="item.icon"
:alt="item.name"
:src="item.icon"
:title="item.name"
class="icon"
/>
<span>{{ item.raw.name }}</span>
<span>{{ item.name }}</span>
</div>
</template>
</v-select>