diff --git a/.vscode/settings.json b/.vscode/settings.json index e764788..bec9644 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -39,6 +39,7 @@ "totvsLanguageServer.welcomePage": false, "cSpell.words": [ "activityinfo", - "Echarts" + "Echarts", + "Typeit" ] // ` } diff --git a/apps/admin/src/components/custom/typeit/index.vue b/apps/admin/src/components/custom/typeit/index.vue index 261ac00..bc2a7bf 100644 --- a/apps/admin/src/components/custom/typeit/index.vue +++ b/apps/admin/src/components/custom/typeit/index.vue @@ -2,44 +2,84 @@ import type { Options } from 'typeit' import type { El } from 'typeit/dist/types' import TypeIt from 'typeit' -import { onMounted, shallowRef } from 'vue' +import { onBeforeUnmount, onMounted, shallowRef, watch } from 'vue' + +defineOptions({ name: 'TypeIt' }) + +const props = withDefaults(defineProps(), { + speed: 100, + loop: false, + cursor: true, + lifeLike: true, + strings: () => [], +}) + +interface Props { + /** 打字速度 */ + speed?: number + /** 是否循环 */ + loop?: boolean + /** 是否显示光标 */ + cursor?: boolean + /** 打字内容 */ + strings?: string | string[] + /** 像人一样打字 */ + lifeLike?: boolean + /** 开始前的延迟 */ + startDelay?: number + /** 下一段文字的延迟 */ + nextStringDelay?: number + /** 循环延迟 */ + loopDelay?: number + /** 兼容旧代码或用户自定义延迟参数 */ + typeDelay?: number +} const textRef = shallowRef() +const typeItInstance = shallowRef(null) function init() { if (!textRef.value) return - const options: Options = { - strings: 'SoybeanAdmin是一个清新优雅、高颜值且功能强大的后台管理模板', - lifeLike: true, - speed: 120, - loop: true, + if (typeItInstance.value) { + typeItInstance.value.destroy() } - const initTypeIt = new TypeIt(textRef.value, options) + // 清空内容,防止重叠 + textRef.value.textContent = '' - initTypeIt.go() + const options: Options = { + strings: props.strings, + lifeLike: props.lifeLike, + speed: props.speed, + loop: props.loop, + cursor: props.cursor, + startDelay: props.startDelay, + nextStringDelay: props.nextStringDelay ?? props.typeDelay, + loopDelay: props.loopDelay, + } + + typeItInstance.value = new TypeIt(textRef.value, options).go() } onMounted(() => { init() }) + +onBeforeUnmount(() => { + if (typeItInstance.value) { + typeItInstance.value.destroy() + } +}) + +watch(() => [props.strings, props.speed, props.loop], () => { + init() +}) diff --git a/apps/admin/src/components/custom/user/CompetitionLayout.vue b/apps/admin/src/components/custom/user/CompetitionLayout.vue index e857577..abf38b0 100644 --- a/apps/admin/src/components/custom/user/CompetitionLayout.vue +++ b/apps/admin/src/components/custom/user/CompetitionLayout.vue @@ -88,6 +88,7 @@ async function fetchSystemConfig() { const showContent = ref(false) const showSlotContent = ref(false) +const showButton = ref(false) function handleBack() { emit('back') @@ -115,10 +116,15 @@ onMounted(() => { }, 100) // 延迟显示内容,等待标题卷轴展开 - const delay = props.showTitle ? 800 : 100 + const delay = props.showTitle ? 500 : 100 setTimeout(() => { showSlotContent.value = true }, delay) + + // 延迟显示按钮,等待内容显示 + setTimeout(() => { + showButton.value = true + }, delay + 500) }) @@ -160,6 +166,7 @@ onMounted(() => {