Browse Source
* fix(Markdown): 修复深色模式 内容区和代码块 未改变主题bug * perf(Markdown): MarkDown组件示例增加不同功能示例; 切换深色主题按钮 同时改变 内容区和代码块主题 * perf(MarkdownViewer): MarkdownViewer改为vditor自带的预览模式; 同时适配深色模式 Co-authored-by: 苗大 <v.caoshm@yoozoo.com>pull/2041/head
committed by
GitHub
4 changed files with 125 additions and 19 deletions
@ -1,23 +1,62 @@ |
|||
<template> |
|||
<!-- eslint-disable vue/no-v-html --> |
|||
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div> |
|||
<div ref="viewerRef" id="markdownViewer" :class="$props.class"></div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { computed, defineProps } from 'vue'; |
|||
import showdown from 'showdown'; |
|||
|
|||
const converter = new showdown.Converter(); |
|||
converter.setOption('tables', true); |
|||
import { defineProps, onBeforeUnmount, onDeactivated, Ref, ref, unref, watch } from 'vue'; |
|||
import VditorPreview from 'vditor/dist/method.min'; |
|||
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated'; |
|||
import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
|||
import { getTheme } from './getTheme'; |
|||
const props = defineProps({ |
|||
value: { type: String }, |
|||
class: { type: String }, |
|||
}); |
|||
const getHtmlData = computed(() => converter.makeHtml(props.value || '')); |
|||
</script> |
|||
const viewerRef = ref<ElRef>(null); |
|||
const vditorPreviewRef = ref(null) as Ref<Nullable<VditorPreview>>; |
|||
const { getDarkMode } = useRootSetting(); |
|||
|
|||
function init() { |
|||
const viewerEl = unref(viewerRef) as HTMLElement; |
|||
vditorPreviewRef.value = VditorPreview.preview(viewerEl, props.value, { |
|||
mode: getTheme(getDarkMode.value, 'content'), |
|||
theme: { |
|||
// 设置内容主题 |
|||
current: getTheme(getDarkMode.value, 'content'), |
|||
}, |
|||
hljs: { |
|||
// 设置代码块主题 |
|||
style: getTheme(getDarkMode.value, 'code'), |
|||
}, |
|||
}); |
|||
} |
|||
watch( |
|||
() => getDarkMode.value, |
|||
(val) => { |
|||
VditorPreview.setContentTheme(getTheme(val, 'content')); |
|||
VditorPreview.setCodeTheme(getTheme(val, 'code')); |
|||
init(); |
|||
}, |
|||
); |
|||
|
|||
<style scoped> |
|||
.markdown-viewer { |
|||
width: 100%; |
|||
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; |
|||
} |
|||
</style> |
|||
|
|||
onMountedOrActivated(init); |
|||
|
|||
onBeforeUnmount(destroy); |
|||
onDeactivated(destroy); |
|||
</script> |
|||
|
|||
@ -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'; |
|||
} |
|||
}; |
|||
Loading…
Reference in new issue