处理 t-link

close #156
This commit is contained in:
BTMuli
2026-01-16 23:27:08 +08:00
parent a2f0a532a8
commit 422f6231c8
9 changed files with 709 additions and 7 deletions

View File

@@ -0,0 +1,56 @@
/**
* hyperlink 组件封装,函数式调用
* @since Beta v0.9.1
*/
import type { ComponentInternalInstance, VNode } from "vue";
import { h, render } from "vue";
import hyperlink from "./hyperlink.vue";
const hyperlinkId = "tg-func-hyperlink";
export type HyperLinkParams = {
/** id */
id: string;
/** 名称 */
name: string;
/**
* 描述
* @remarks htmlText
*/
desc: string;
};
/**
* 自定义 HyperLink 组件
* @since Beta v0.6.3
*/
type HyperLinkInstance = {
exposeProxy: {
displayBox: (props: HyperLinkParams) => Promise<void>;
};
} & ComponentInternalInstance;
function renderBox(props: HyperLinkParams): VNode {
const container = document.createElement("div");
container.id = hyperlinkId;
const boxVNode: VNode = h(hyperlink, props);
render(boxVNode, container);
document.body.appendChild(container);
return boxVNode;
}
let hyperLinkInstance: VNode;
async function showHyperLink(info: HyperLinkParams): Promise<void> {
if (hyperLinkInstance !== undefined) {
const boxVue = <HyperLinkInstance>hyperLinkInstance.component;
await boxVue.exposeProxy.displayBox(info);
} else {
hyperLinkInstance = renderBox(info);
await showHyperLink(info);
}
}
export default showHyperLink;

View File

@@ -0,0 +1,146 @@
<!-- HyperLink Overlay -->
<template>
<transition name="func-hyperlink">
<div v-show="show || showOuter" class="hyperlink-overlay" @click.self.prevent="handleOuter">
<transition name="func-hyperlink-inner">
<div v-show="showInner" class="hyperlink-box">
<div class="hyperlink-title">{{ data.name }}</div>
<div class="hyperlink-desc">
<span v-html="parseHtmlText(data.desc)" />
</div>
<div class="hyperlink-id">{{ data.id }}</div>
</div>
</transition>
</div>
</transition>
</template>
<script lang="ts" setup>
import { parseHtmlText } from "@utils/toolFunc.js";
import { onMounted, ref, shallowRef, watch } from "vue";
import type { HyperLinkParams } from "./hyperlink.js";
const show = ref<boolean>(false);
const showOuter = ref<boolean>(false);
const showInner = ref<boolean>(false);
const props = defineProps<HyperLinkParams>();
const data = shallowRef<HyperLinkParams>(props);
watch(
() => show.value,
async () => {
if (show.value) {
showOuter.value = true;
await new Promise<void>((resolve) => setTimeout(resolve, 100));
showInner.value = true;
return;
}
await new Promise<void>((resolve) => setTimeout(resolve, 100));
showInner.value = false;
await new Promise<void>((resolve) => setTimeout(resolve, 300));
showOuter.value = false;
},
);
onMounted(async () => await displayBox(props));
function handleOuter(): void {
show.value = false;
}
async function displayBox(params: HyperLinkParams): Promise<void> {
data.value = params;
show.value = true;
}
defineExpose({ displayBox });
</script>
<style lang="scss" scoped>
.func-hyperlink-outer-enter-active,
.func-hyperlink-outer-leave-active,
.func-hyperlink-inner-enter-active {
transition: all 0.3s;
}
.func-hyperlink-inner-leave-active {
transition: all 0.5s ease-in-out;
}
.func-hyperlink-inner-enter-from {
opacity: 0;
transform: scale(1.5);
}
.func-hyperlink-inner-enter-to,
.func-hyperlink-inner-leave-from {
opacity: 1;
transform: scale(1);
}
.func-hyperlink-outer-enter-to,
.func-hyperlink-outer-leave-from {
opacity: 1;
}
.func-hyperlink-outer-enter-from,
.func-hyperlink-outer-leave-to {
opacity: 0;
}
.func-hyperlink-inner-leave-to {
opacity: 0;
transform: scale(0);
}
.hyperlink-overlay {
position: fixed;
z-index: var(--tgi-hyperlink);
top: 0;
left: 0;
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
.hyperlink-box {
position: relative;
display: flex;
width: 520px;
height: 240px;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 10px 10px 16px;
border: 1px solid var(--common-shadow-1);
border-radius: 8px;
background: var(--app-page-bg);
box-shadow: 0 0 10px var(--common-shadow-t-1);
color: var(--app-page-content);
}
.hyperlink-title {
position: relative;
color: var(--common-text-title);
font-family: var(--font-title);
font-size: 20px;
}
.hyperlink-desc {
position: relative;
padding-right: 8px;
overflow-y: auto;
white-space: pre-wrap;
}
.hyperlink-id {
position: absolute;
right: 8px;
bottom: 0;
font-size: 12px;
}
</style>