feat: 前端组件准备

This commit is contained in:
2026-05-22 15:02:31 +08:00
parent 397ccdca13
commit 5e05bf4f63
62 changed files with 6903 additions and 878 deletions
+78
View File
@@ -0,0 +1,78 @@
<script setup lang="ts">
const emit = defineEmits<{
(e: "change", changed: boolean): void;
}>();
let hideTimer: NodeJS.Timeout | null = null;
/** 是否发生变化 */
const hasChanged = ref(false);
/** 上一次的内容,用于对比变化 */
const previousContent = ref("");
/* 是否初次渲染 */
const isInitialized = ref(false);
const cellRef = useTemplateRef<HTMLElement | null>("cellRef");
const checkChange = async () => {
await nextTick();
if (!cellRef.value) return;
const currentContent = cellRef.value?.textContent?.trim() || "";
if (!isInitialized.value) {
// 首次渲染,记录原始值
previousContent.value = currentContent;
isInitialized.value = true;
hasChanged.value = false;
} else {
// 对比变化
hasChanged.value = currentContent !== previousContent.value;
emit("change", hasChanged.value);
}
};
watch(hasChanged, (newVal) => {
if (newVal) {
if (hideTimer) clearTimeout(hideTimer);
hideTimer = setTimeout(() => {
hasChanged.value = false;
emit("change", false);
previousContent.value = cellRef.value?.textContent?.trim() || "";
}, 1000);
}
});
let observer: MutationObserver | null = null;
watch(
cellRef,
(el) => {
observer?.disconnect();
if (el) {
checkChange();
observer = new MutationObserver(checkChange);
observer.observe(el, {
childList: true,
subtree: true,
characterData: true
});
}
},
{ immediate: true }
);
</script>
<template>
<div
ref="cellRef"
class="transition-colors duration-300"
:class="{ 'bg-[#ECF2FF] h-full w-full p-4 -my-4': hasChanged }"
>
<slot />
</div>
</template>