diff --git a/src/components/Markdown/src/Markdown.vue b/src/components/Markdown/src/Markdown.vue index d8117631..c80c779b 100644 --- a/src/components/Markdown/src/Markdown.vue +++ b/src/components/Markdown/src/Markdown.vue @@ -19,6 +19,7 @@ import { useModalContext } from '../../Modal'; import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated'; + import { getTheme } from './getTheme'; type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined; @@ -46,8 +47,9 @@ if (!inited) { return; } - const theme = val === 'dark' ? 'dark' : 'classic'; - instance.getVditor()?.setTheme(theme); + instance + .getVditor() + ?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code')); }, { immediate: true, @@ -87,13 +89,22 @@ if (!wrapEl) return; const bindValue = { ...attrs, ...props }; const insEditor = new Vditor(wrapEl, { - theme: getDarkMode.value === 'dark' ? 'dark' : 'classic', + // 设置外观主题 + theme: getTheme(getDarkMode.value) as any, lang: unref(getCurrentLang), mode: 'sv', fullscreen: { index: 520, }, preview: { + theme: { + // 设置内容主题 + current: getTheme(getDarkMode.value, 'content'), + }, + hljs: { + // 设置代码块主题 + style: getTheme(getDarkMode.value, 'code'), + }, actions: [], }, input: (v) => { diff --git a/src/components/Markdown/src/MarkdownViewer.vue b/src/components/Markdown/src/MarkdownViewer.vue index 708aa86e..538cedaf 100644 --- a/src/components/Markdown/src/MarkdownViewer.vue +++ b/src/components/Markdown/src/MarkdownViewer.vue @@ -1,23 +1,62 @@ + const viewerRef = ref(null); + const vditorPreviewRef = ref(null) as Ref>; + const { getDarkMode } = useRootSetting(); - + watch( + () => getDarkMode.value, + (val) => { + VditorPreview.setContentTheme(getTheme(val, 'content')); + VditorPreview.setCodeTheme(getTheme(val, 'code')); + init(); + }, + ); + + watch( + () => props.value, + (v, oldValue) => { + v !== oldValue && init(); + }, + ); + + function destroy() { + const vditorInstance = unref(vditorPreviewRef); + if (!vditorInstance) return; + try { + vditorInstance?.destroy?.(); + } catch (error) {} + vditorPreviewRef.value = null; + } + + onMountedOrActivated(init); + + onBeforeUnmount(destroy); + onDeactivated(destroy); + diff --git a/src/components/Markdown/src/getTheme.ts b/src/components/Markdown/src/getTheme.ts new file mode 100644 index 00000000..fcfe9d36 --- /dev/null +++ b/src/components/Markdown/src/getTheme.ts @@ -0,0 +1,19 @@ +/** + * 获取主题类型 深色浅色模式 对应的值 + * @param darkModeVal 深色模式值 + * @param themeMode 主题类型——外观(默认), 内容, 代码块 + */ +export const getTheme = ( + darkModeVal: 'light' | 'dark' | string, + themeMode: 'default' | 'content' | 'code' = 'default', +) => { + const isDark = darkModeVal === 'dark'; + switch (themeMode) { + case 'default': + return isDark ? 'dark' : 'classic'; + case 'content': + return isDark ? 'dark' : 'light'; + case 'code': + return isDark ? 'dracula' : 'github'; + } +}; diff --git a/src/views/demo/editor/markdown/index.vue b/src/views/demo/editor/markdown/index.vue index 968bd910..d88689c9 100644 --- a/src/views/demo/editor/markdown/index.vue +++ b/src/views/demo/editor/markdown/index.vue @@ -28,16 +28,53 @@ setup() { const markDownRef = ref>(null); const valueRef = ref(` -# title +# 标题h1 -# content +##### 标题h5 + +**加粗** +*斜体* +~~删除线~~ +[链接](https://github.com/vbenjs/vue-vben-admin) +↓分割线↓ + +--- + + +* 无序列表1 + * 无序列表1.1 + +1. 有序列表1 +2. 有序列表2 + +* [ ] 任务列表1 +* [x] 任务列表2 + +> 引用示例 + +\`\`\`js +// 代码块: +(() => { + var htmlRoot = document.getElementById('htmlRoot'); + var theme = window.localStorage.getItem('__APP__DARK__MODE__'); + if (htmlRoot && theme) { + htmlRoot.setAttribute('data-theme', theme); + theme = htmlRoot = null; + } +})(); +\`\`\` + +| 表格 | 示例 | 🎉️ | +| --- | --- | --- | +| 1 | 2 | 3 | +| 4 | 5 | 6 | `); function toggleTheme() { const markDown = unref(markDownRef); if (!markDown) return; const vditor = markDown.getVditor(); - vditor.setTheme('dark'); + vditor.setTheme('dark', 'dark', 'dracula'); } function handleChange(v: string) {