初始版本提交

This commit is contained in:
yaoyn
2024-02-05 09:15:37 +08:00
parent b52d4414be
commit 445292105f
1848 changed files with 236859 additions and 75 deletions

View File

@ -0,0 +1,7 @@
import { withInstall } from '/@/utils';
import markDown from './src/Markdown.vue';
import markDownViewer from './src/MarkdownViewer.vue';
export const MarkDown = withInstall(markDown);
export const MarkdownViewer = withInstall(markDownViewer);
export * from './src/typing';

View File

@ -0,0 +1,147 @@
<template>
<div ref="wrapRef"></div>
</template>
<script lang="ts">
import type { Ref } from 'vue';
import {
defineComponent,
ref,
unref,
nextTick,
computed,
watch,
onBeforeUnmount,
onDeactivated,
} from 'vue';
import Vditor from 'vditor';
import 'vditor/dist/index.css';
import { useLocale } from '/@/locales/useLocale';
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;
export default defineComponent({
inheritAttrs: false,
props: {
height: { type: Number, default: 360 },
value: { type: String, default: '' },
},
emits: ['change', 'get', 'update:value'],
setup(props, { attrs, emit }) {
const wrapRef = ref<ElRef>(null);
const vditorRef = ref(null) as Ref<Nullable<Vditor>>;
const initedRef = ref(false);
const modalFn = useModalContext();
const { getLocale } = useLocale();
const { getDarkMode } = useRootSetting();
const valueRef = ref(props.value || '');
watch(
[() => getDarkMode.value, () => initedRef.value],
([val, inited]) => {
if (!inited) {
return;
}
instance
.getVditor()
?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'));
},
{
immediate: true,
flush: 'post',
},
);
watch(
() => props.value,
(v) => {
if (v !== valueRef.value) {
instance.getVditor()?.setValue(v);
}
valueRef.value = v;
},
);
const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
let lang: Lang;
switch (unref(getLocale)) {
case 'en':
lang = 'en_US';
break;
case 'ja':
lang = 'ja_JP';
break;
case 'ko':
lang = 'ko_KR';
break;
default:
lang = 'zh_CN';
}
return lang;
});
function init() {
const wrapEl = unref(wrapRef) as HTMLElement;
if (!wrapEl) return;
const bindValue = { ...attrs, ...props };
const insEditor = new Vditor(wrapEl, {
// 设置外观主题
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) => {
valueRef.value = v;
emit('update:value', v);
emit('change', v);
},
after: () => {
nextTick(() => {
modalFn?.redoModalHeight?.();
insEditor.setValue(valueRef.value);
vditorRef.value = insEditor;
initedRef.value = true;
emit('get', instance);
});
},
blur: () => {
//unref(vditorRef)?.setValue(props.value);
},
...bindValue,
cache: {
enable: false,
},
});
}
const instance = {
getVditor: (): Vditor => vditorRef.value!,
};
function destroy() {
const vditorInstance = unref(vditorRef);
if (!vditorInstance) return;
try {
vditorInstance?.destroy?.();
} catch (error) {}
vditorRef.value = null;
initedRef.value = false;
}
onMountedOrActivated(init);
onBeforeUnmount(destroy);
onDeactivated(destroy);
return {
wrapRef,
...instance,
};
},
});
</script>

View File

@ -0,0 +1,57 @@
<template>
<div ref="viewerRef" id="markdownViewer" :class="$props.class"></div>
</template>
<script lang="ts" setup>
import { 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 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();
},
);
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>

View File

@ -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';
}
};

View File

@ -0,0 +1,4 @@
import Vditor from 'vditor';
export interface MarkDownActionType {
getVditor: () => Vditor;
}