From c860621e7acf6d6bd3b8e0f3538cf1bd7676177f Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Fri, 14 Nov 2025 00:00:00 +0800 Subject: [PATCH] =?UTF-8?q?feat!:=20=E5=B0=86QuestionList=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=B8=B2=E6=9F=93=E7=94=B1Markdown=E6=94=B9?= =?UTF-8?q?=E4=B8=BAHTML?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端CMS字段由Markdown改为WYSIWYG因此前端做出对应修改 --- app/assets/css/typography.css | 53 +++++++++++++++ app/components/shared/HtmlRenderer.ts | 30 +++++++++ app/components/shared/QuestionList.vue | 15 ++++- app/composables/useHtmlRenderer.ts | 80 +++++++++++++++++++++++ app/utils/htmlDefaultMap.ts | 30 +++++++++ app/utils/parseTable.ts | 90 ++++++++++++++++++++++++++ nuxt.config.ts | 1 + package.json | 2 + pnpm-lock.yaml | 22 +++++++ 9 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 app/assets/css/typography.css create mode 100644 app/components/shared/HtmlRenderer.ts create mode 100644 app/composables/useHtmlRenderer.ts create mode 100644 app/utils/htmlDefaultMap.ts create mode 100644 app/utils/parseTable.ts diff --git a/app/assets/css/typography.css b/app/assets/css/typography.css new file mode 100644 index 0000000..19ffa0e --- /dev/null +++ b/app/assets/css/typography.css @@ -0,0 +1,53 @@ +.html-typography { + padding: 10px; + ling-height: 1.6; +} + +.html-typography h1 { + color: var(--el-color-primary); + font-size: 1.5em; + margin-bottom: 0.5em; + text-align: center; +} + +.html-typography h2 { + color: var(--el-color-primary); + font-size: 1.5em; + margin-bottom: 0.5em; +} + +.html-typography h3 { + color: var(--el-color-primary); + font-size: 1.2em; + margin-bottom: 0.5em; +} + +.html-typography p { + text-indent: 2em; + text-align: justify; + margin: 0.5em 0; + margin-bottom: 1em; +} + +.html-typography ol { + list-style-type: decimal; + padding-left: 2em; + margin-bottom: 1em; +} + +.html-typography ul { + list-style-type: disc; + padding-left: 2em; + margin-bottom: 1em; +} + +.html-typography hr { + border: none; + border-top: 1px solid var(--el-border-color); + margin: 20px 0; +} + +.html-typography table { + width: 100%; + border: 1px solid var(--el-border-color); +} diff --git a/app/components/shared/HtmlRenderer.ts b/app/components/shared/HtmlRenderer.ts new file mode 100644 index 0000000..3cae08c --- /dev/null +++ b/app/components/shared/HtmlRenderer.ts @@ -0,0 +1,30 @@ +export default defineComponent({ + name: 'HtmlRenderer', + + props: { + html: { + type: String, + required: true, + }, + map: { + type: Object as () => HtmlRenderMap, + default: () => defaultHtmlRenderMap, + }, + allowUnknown: { + type: Boolean, + default: true, + }, + }, + + setup(props, { attrs }) { + const nodes: VNode[] = useHtmlRenderer(props.html, { + map: props.map, + allowUnknownTags: props.allowUnknown, + }); + + logger.debug('nodes: ', nodes); + + // 渲染函数:直接返回 VNode 数组 + return () => h('div', { ...attrs }, nodes); + }, +}); diff --git a/app/components/shared/QuestionList.vue b/app/components/shared/QuestionList.vue index cb64b07..c0d93db 100644 --- a/app/components/shared/QuestionList.vue +++ b/app/components/shared/QuestionList.vue @@ -8,7 +8,14 @@ :title="question.title" :name="question.id" > - + +
+
+ +
@@ -25,6 +32,8 @@ const activeNames = ref<(string | number)[]>([]); + const hydrated = ref(false); + // 当路由变化(包括初次挂载)时,检查是否需要聚焦 watch( () => route.query.focus, @@ -47,6 +56,10 @@ }, { immediate: true } ); + + onMounted(() => { + hydrated.value = true; + });