Commit d95815b5031984e224140eb1b1d46e2dbf80abc1
1 parent
0a3683a1
fix(markdown): resolving markdown exceptions
修复markdown组件的异常以及不能正确设置value的问题
Showing
3 changed files
with
54 additions
and
27 deletions
CHANGELOG.zh_CN.md
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 | }); | ... | ... |