Commit d95815b5031984e224140eb1b1d46e2dbf80abc1

Authored by 无木
1 parent 0a3683a1

fix(markdown): resolving markdown exceptions

修复markdown组件的异常以及不能正确设置value的问题
CHANGELOG.zh_CN.md
... ... @@ -21,6 +21,7 @@
21 21 - 修复顶栏菜单在显示包含需要隐藏的菜单项目时出错的问题
22 22 - 修复悬停触发模式下左侧混合菜单会在没有子菜单且被激活时直接跳转路由
23 23 - **Breadcrumb** 修复带有重定向的菜单点击无法跳转的问题
  24 +- **Markdown** 修复初始化异常以及不能正确地动态设置 value 的问题
24 25 - **其它**
25 26 - 修复菜单默认折叠的配置不起作用的问题
26 27 - 修复`safari`浏览器报错导致网站打不开
... ...
src/components/Markdown/src/Markdown.vue
... ... @@ -5,18 +5,19 @@
5 5 import {
6 6 defineComponent,
7 7 ref,
8   - onMounted,
9 8 unref,
10   - onUnmounted,
11 9 nextTick,
12 10 computed,
13 11 watch,
  12 + onBeforeUnmount,
  13 + onDeactivated,
14 14 } from 'vue';
15 15 import Vditor from 'vditor';
16 16 import 'vditor/dist/index.css';
17 17 import { useLocale } from '/@/locales/useLocale';
18 18 import { useModalContext } from '../../Modal';
19 19 import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  20 + import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
20 21  
21 22 type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
22 23  
... ... @@ -26,7 +27,7 @@
26 27 height: { type: Number, default: 360 },
27 28 value: { type: String, default: '' },
28 29 },
29   - emits: ['change', 'get'],
  30 + emits: ['change', 'get', 'update:value'],
30 31 setup(props, { attrs, emit }) {
31 32 const wrapRef = ref<ElRef>(null);
32 33 const vditorRef = ref<Nullable<Vditor>>(null);
... ... @@ -36,17 +37,16 @@
36 37  
37 38 const { getLocale } = useLocale();
38 39 const { getDarkMode } = useRootSetting();
  40 + const valueRef = ref('');
39 41  
40 42 watch(
41 43 [() => getDarkMode.value, () => initedRef.value],
42   - ([val]) => {
43   - const vditor = unref(vditorRef);
44   -
45   - if (!vditor) {
  44 + ([val, inited]) => {
  45 + if (!inited) {
46 46 return;
47 47 }
48   - const theme = val === 'dark' ? 'dark' : undefined;
49   - vditor.setTheme(theme as 'dark');
  48 + const theme = val === 'dark' ? 'dark' : 'classic';
  49 + instance.getVditor()?.setTheme(theme);
50 50 },
51 51 {
52 52 immediate: true,
... ... @@ -54,6 +54,16 @@
54 54 }
55 55 );
56 56  
  57 + watch(
  58 + () => props.value,
  59 + (v) => {
  60 + if (v !== valueRef.value) {
  61 + instance.getVditor()?.setValue(v);
  62 + valueRef.value = v;
  63 + }
  64 + }
  65 + );
  66 +
57 67 const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
58 68 let lang: Lang;
59 69 switch (unref(getLocale)) {
... ... @@ -72,54 +82,59 @@
72 82 return lang;
73 83 });
74 84 function init() {
75   - const wrapEl = unref(wrapRef);
  85 + const wrapEl = unref(wrapRef) as HTMLElement;
76 86 if (!wrapEl) return;
77 87 const bindValue = { ...attrs, ...props };
78 88 vditorRef.value = new Vditor(wrapEl, {
79   - theme: 'classic',
  89 + theme: getDarkMode.value === 'dark' ? 'dark' : 'classic',
80 90 lang: unref(getCurrentLang),
81 91 mode: 'sv',
82 92 preview: {
83 93 actions: [],
84 94 },
85 95 input: (v) => {
86   - // emit('update:value', v);
  96 + valueRef.value = v;
  97 + emit('update:value', v);
87 98 emit('change', v);
88 99 },
  100 + after: () => {
  101 + nextTick(() => {
  102 + modalFn?.redoModalHeight?.();
  103 + initedRef.value = true;
  104 + });
  105 + },
89 106 blur: () => {
90   - unref(vditorRef)?.setValue(props.value);
  107 + //unref(vditorRef)?.setValue(props.value);
91 108 },
92 109 ...bindValue,
93 110 cache: {
94 111 enable: false,
95 112 },
96 113 });
97   - initedRef.value = true;
98 114 }
99 115  
100 116 const instance = {
101 117 getVditor: (): Vditor => vditorRef.value!,
102 118 };
103 119  
104   - onMounted(() => {
105   - nextTick(() => {
106   - init();
107   - setTimeout(() => {
108   - modalFn?.redoModalHeight?.();
109   - }, 200);
110   - });
111   -
112   - emit('get', instance);
113   - });
114   -
115   - onUnmounted(() => {
  120 + function destroy() {
116 121 const vditorInstance = unref(vditorRef);
117 122 if (!vditorInstance) return;
118 123 try {
119 124 vditorInstance?.destroy?.();
120 125 } catch (error) {}
  126 + vditorRef.value = null;
  127 + }
  128 +
  129 + onMountedOrActivated(() => {
  130 + nextTick(() => {
  131 + init();
  132 + });
  133 + emit('get', instance);
121 134 });
122 135  
  136 + onBeforeUnmount(destroy);
  137 + onDeactivated(destroy);
123 138 return {
124 139 wrapRef,
125 140 ...instance,
... ...
src/views/demo/editor/markdown/index.vue
1 1 <template>
2 2 <PageWrapper title="MarkDown组件示例">
3 3 <a-button @click="toggleTheme" class="mb-2" type="primary"> 黑暗主题 </a-button>
4   - <MarkDown :value="value" @change="handleChange" ref="markDownRef" />
  4 + <a-button @click="clearValue" class="mb-2" type="default"> 清空内容 </a-button>
  5 + <MarkDown
  6 + v-model:value="value"
  7 + @change="handleChange"
  8 + ref="markDownRef"
  9 + placeholder="这是占位文本"
  10 + />
5 11 </PageWrapper>
6 12 </template>
7 13 <script lang="ts">
... ... @@ -30,11 +36,16 @@
30 36 valueRef.value = v;
31 37 }
32 38  
  39 + function clearValue() {
  40 + valueRef.value = '';
  41 + }
  42 +
33 43 return {
34 44 value: valueRef,
35 45 toggleTheme,
36 46 markDownRef,
37 47 handleChange,
  48 + clearValue,
38 49 };
39 50 },
40 51 });
... ...