🚸 优化名片Wiki样式

This commit is contained in:
BTMuli
2025-09-10 00:30:19 +08:00
parent 1a27dc5f02
commit fd47ebe7c1

View File

@@ -1,22 +1,53 @@
<!-- TODO: UI一致性&类别筛选 -->
<template> <template>
<div class="tw-nc-box"> <v-app-bar>
<v-text-field <template #prepend>
v-model="search" <div class="wnc-top-prepend">
prepend-inner-icon="mdi-magnify" <div class="title">
label="搜索" <v-icon>mdi-credit-card-outline</v-icon>
:hide-details="true" <span>名片图鉴</span>
variant="outlined" </div>
@click:prepend-inner="searchNameCard()" <v-select
@keyup.enter="searchNameCard()" v-model="selectType"
/> :items="namecardTypes"
<div class="tw-nc-list"> item-title="type"
<v-virtual-scroll :items="sortNameCardsData" :item-height="80" item-key="id"> :hide-details="true"
<template #default="{ item }"> :clearable="true"
<TopNameCard :data="item" @selected="showNameCard(item)" /> width="250px"
</template> label="名片类别"
</v-virtual-scroll> density="compact"
</div> variant="outlined"
>
<template #item="{ props, item }">
<v-list-item v-bind="props">
<template #append>
<v-chip>{{ item.raw.number }}</v-chip>
</template>
</v-list-item>
</template>
</v-select>
</div>
</template>
<template #append>
<div class="wnc-top-append">
<v-text-field
v-model="search"
density="compact"
prepend-inner-icon="mdi-magnify"
label="搜索"
:hide-details="true"
variant="outlined"
@click:prepend-inner="searchNameCard()"
@keyup.enter="searchNameCard()"
/>
</div>
</template>
</v-app-bar>
<div class="tw-nc-list">
<v-virtual-scroll class="v-scroll" :items="sortNameCardsData" :item-height="80" item-key="id">
<template #default="{ item }">
<TopNameCard :data="item" @selected="showNameCard(item)" />
</template>
</v-virtual-scroll>
</div> </div>
<ToNameCard v-model="visible" :data="curNameCard"> <ToNameCard v-model="visible" :data="curNameCard">
<template #left> <template #left>
@@ -35,18 +66,46 @@
import ToNameCard from "@comp/app/to-nameCard.vue"; import ToNameCard from "@comp/app/to-nameCard.vue";
import TopNameCard from "@comp/app/top-nameCard.vue"; import TopNameCard from "@comp/app/top-nameCard.vue";
import showSnackbar from "@comp/func/snackbar.js"; import showSnackbar from "@comp/func/snackbar.js";
import { onMounted, ref, shallowRef } from "vue"; import { onMounted, ref, shallowRef, watch } from "vue";
import { AppNameCardsData } from "@/data/index.js"; import { AppNameCardsData } from "@/data/index.js";
type NameCardType = { type: string; number: number };
const curIndex = ref<number>(0); const curIndex = ref<number>(0);
const total = ref<number>(0); const total = ref<number>(0);
const visible = ref<boolean>(false); const visible = ref<boolean>(false);
const search = ref<string>(); const search = ref<string>();
const selectType = ref<string | null>(null);
const namecardTypes = shallowRef<Array<NameCardType>>([]);
const curNameCard = shallowRef<TGApp.App.NameCard.Item>(); const curNameCard = shallowRef<TGApp.App.NameCard.Item>();
const sortNameCardsData = shallowRef<Array<TGApp.App.NameCard.Item>>([]); const sortNameCardsData = shallowRef<Array<TGApp.App.NameCard.Item>>([]);
onMounted(() => sortData(AppNameCardsData)); onMounted(() => {
const tmpData: Array<NameCardType> = [];
for (const item of AppNameCardsData) {
const typeFindIndex = tmpData.findIndex((itemT) => itemT.type === item.type);
if (typeFindIndex === -1) {
const itemN: NameCardType = { type: item.type, number: 1 };
tmpData.push(itemN);
continue;
}
tmpData[typeFindIndex].number++;
}
namecardTypes.value = tmpData;
sortData(AppNameCardsData);
showSnackbar.success(`成功获取${sortNameCardsData.value.length}条数据`);
});
watch(
() => selectType.value,
() => sortData(getSelectNameCards()),
);
function getSelectNameCards(): TGApp.App.NameCard.Item[] {
if (selectType.value === null) return AppNameCardsData;
else return AppNameCardsData.filter((item) => item.type === selectType.value);
}
function sortData(data: TGApp.App.NameCard.Item[]): void { function sortData(data: TGApp.App.NameCard.Item[]): void {
sortNameCardsData.value = data.sort((a, b) => a.type.localeCompare(b.type) || a.id - b.id); sortNameCardsData.value = data.sort((a, b) => a.type.localeCompare(b.type) || a.id - b.id);
@@ -98,16 +157,43 @@ function searchNameCard(): void {
} }
</script> </script>
<style lang="css" scoped> <style lang="css" scoped>
.tw-nc-box { .wnc-top-prepend {
position: relative;
display: flex; display: flex;
flex-direction: column; align-items: center;
row-gap: 10px; justify-content: flex-start;
margin-left: 16px;
column-gap: 16px;
.title {
position: relative;
display: flex;
align-items: center;
justify-content: center;
color: var(--common-text-title);
column-gap: 4px;
font-family: var(--font-title);
font-size: 20px;
}
}
.wnc-top-append {
position: relative;
width: 600px;
margin-right: 16px;
} }
.tw-nc-list { .tw-nc-list {
position: relative;
display: flex;
overflow: auto; overflow: auto;
height: calc(100vh - 100px); height: calc(100vh - 100px);
padding-right: 10px; flex-direction: column;
row-gap: 10px;
.v-scroll {
padding-right: 8px;
}
} }
.card-arrow { .card-arrow {