Unverified 提交 a89e497e 作者: Wit〆苗大 提交者: GitHub

fix: markdown深色模式内容区和代码块未适配bug; markdownViewer改为vidtor自带预览模式 (#2023)

* fix(Markdown): 修复深色模式 内容区和代码块 未改变主题bug

* perf(Markdown): MarkDown组件示例增加不同功能示例; 切换深色主题按钮 同时改变 内容区和代码块主题

* perf(MarkdownViewer): MarkdownViewer改为vditor自带的预览模式; 同时适配深色模式

Co-authored-by: 苗大 <v.caoshm@yoozoo.com>
上级 0f50e045
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
import { useModalContext } from '../../Modal'; import { useModalContext } from '../../Modal';
import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated'; import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
import { getTheme } from './getTheme';
type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined; type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
...@@ -46,8 +47,9 @@ ...@@ -46,8 +47,9 @@
if (!inited) { if (!inited) {
return; return;
} }
const theme = val === 'dark' ? 'dark' : 'classic'; instance
instance.getVditor()?.setTheme(theme); .getVditor()
?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'));
}, },
{ {
immediate: true, immediate: true,
...@@ -87,13 +89,22 @@ ...@@ -87,13 +89,22 @@
if (!wrapEl) return; if (!wrapEl) return;
const bindValue = { ...attrs, ...props }; const bindValue = { ...attrs, ...props };
const insEditor = new Vditor(wrapEl, { const insEditor = new Vditor(wrapEl, {
theme: getDarkMode.value === 'dark' ? 'dark' : 'classic', // 设置外观主题
theme: getTheme(getDarkMode.value) as any,
lang: unref(getCurrentLang), lang: unref(getCurrentLang),
mode: 'sv', mode: 'sv',
fullscreen: { fullscreen: {
index: 520, index: 520,
}, },
preview: { preview: {
theme: {
// 设置内容主题
current: getTheme(getDarkMode.value, 'content'),
},
hljs: {
// 设置代码块主题
style: getTheme(getDarkMode.value, 'code'),
},
actions: [], actions: [],
}, },
input: (v) => { input: (v) => {
......
<template> <template>
<!-- eslint-disable vue/no-v-html --> <div ref="viewerRef" id="markdownViewer" :class="$props.class"></div>
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, defineProps } from 'vue'; import { defineProps, onBeforeUnmount, onDeactivated, Ref, ref, unref, watch } from 'vue';
import showdown from 'showdown'; import VditorPreview from 'vditor/dist/method.min';
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
const converter = new showdown.Converter(); import { useRootSetting } from '/@/hooks/setting/useRootSetting';
converter.setOption('tables', true); import { getTheme } from './getTheme';
const props = defineProps({ const props = defineProps({
value: { type: String }, value: { type: String },
class: { type: String }, class: { type: String },
}); });
const getHtmlData = computed(() => converter.makeHtml(props.value || '')); const viewerRef = ref<ElRef>(null);
</script> const vditorPreviewRef = ref(null) as Ref<Nullable<VditorPreview>>;
const { getDarkMode } = useRootSetting();
<style scoped> function init() {
.markdown-viewer { const viewerEl = unref(viewerRef) as HTMLElement;
width: 100%; vditorPreviewRef.value = VditorPreview.preview(viewerEl, props.value, {
mode: getTheme(getDarkMode.value, 'content'),
theme: {
// 设置内容主题
current: getTheme(getDarkMode.value, 'content'),
},
hljs: {
// 设置代码块主题
style: getTheme(getDarkMode.value, 'code'),
},
});
} }
</style> 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);
</script>
/**
* 获取主题类型 深色浅色模式 对应的值
* @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';
}
};
...@@ -28,16 +28,53 @@ ...@@ -28,16 +28,53 @@
setup() { setup() {
const markDownRef = ref<Nullable<MarkDownActionType>>(null); const markDownRef = ref<Nullable<MarkDownActionType>>(null);
const valueRef = ref(` 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() { function toggleTheme() {
const markDown = unref(markDownRef); const markDown = unref(markDownRef);
if (!markDown) return; if (!markDown) return;
const vditor = markDown.getVditor(); const vditor = markDown.getVditor();
vditor.setTheme('dark'); vditor.setTheme('dark', 'dark', 'dracula');
} }
function handleChange(v: string) { function handleChange(v: string) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论