Skip to content

Commit 5fb069f

Browse files
committed
feat: add markdown component
1 parent 2fbc450 commit 5fb069f

File tree

8 files changed

+177
-0
lines changed

8 files changed

+177
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"nprogress": "^0.2.0",
3131
"path-to-regexp": "^6.2.0",
3232
"qrcode": "^1.4.4",
33+
"vditor": "^3.5.5",
3334
"vue": "^3.0.1",
3435
"vue-i18n": "^9.0.0-beta.4",
3536
"vue-router": "^4.0.0-beta.13",

src/components/Markdown/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as MarkDown } from './src/index.vue';
2+
3+
export * from './src/types';
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<template>
2+
<div class="markdown" ref="wrapRef" />
3+
</template>
4+
<script lang="ts">
5+
import {
6+
defineComponent,
7+
ref,
8+
onMounted,
9+
unref,
10+
PropType,
11+
onUnmounted,
12+
nextTick,
13+
watchEffect,
14+
} from 'vue';
15+
import Vditor from 'vditor';
16+
import 'vditor/dist/index.css';
17+
export default defineComponent({
18+
emits: ['update:value'],
19+
props: {
20+
height: {
21+
type: Number as PropType<number>,
22+
default: 360,
23+
},
24+
value: {
25+
type: String,
26+
default: '',
27+
},
28+
},
29+
setup(props, { attrs, emit }) {
30+
const wrapRef = ref<Nullable<HTMLDivElement>>(null);
31+
const vditorRef = ref<Nullable<Vditor>>(null);
32+
33+
const initedRef = ref(false);
34+
35+
function init() {
36+
const wrapEl = unref(wrapRef);
37+
if (!wrapEl) return;
38+
const data = { ...attrs, ...props };
39+
vditorRef.value = new Vditor(wrapEl, {
40+
mode: 'sv',
41+
preview: {
42+
actions: [],
43+
},
44+
input: (v) => {
45+
emit('update:value', v);
46+
},
47+
...data,
48+
cache: {
49+
enable: false,
50+
},
51+
});
52+
initedRef.value = true;
53+
}
54+
55+
watchEffect(() => {
56+
nextTick(() => {
57+
const vditor = unref(vditorRef);
58+
if (unref(initedRef) && props.value && vditor) {
59+
vditor.setValue(props.value);
60+
}
61+
});
62+
});
63+
64+
onMounted(() => {
65+
nextTick(() => {
66+
init();
67+
});
68+
});
69+
70+
onUnmounted(() => {
71+
const vditorInstance = unref(vditorRef);
72+
if (!vditorInstance) return;
73+
vditorInstance.destroy();
74+
});
75+
76+
return {
77+
wrapRef,
78+
getVditor: (): Vditor => vditorRef.value!,
79+
};
80+
},
81+
});
82+
</script>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Vditor from 'vditor';
2+
export interface MarkDownActionType {
3+
getVditor: () => Vditor;
4+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { MenuModule } from '/@/router/types.d';
2+
const menu: MenuModule = {
3+
orderNo: 500,
4+
menu: {
5+
name: '编辑器',
6+
path: '/editor',
7+
children: [
8+
{
9+
path: '/markdown',
10+
name: 'markdown编辑器',
11+
},
12+
],
13+
},
14+
};
15+
export default menu;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { AppRouteModule } from '/@/router/types';
2+
3+
import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant';
4+
5+
export default {
6+
layout: {
7+
path: '/editor',
8+
name: 'Editor',
9+
component: PAGE_LAYOUT_COMPONENT,
10+
redirect: '/editor/markdown',
11+
meta: {
12+
icon: 'ant-design:table-outlined',
13+
title: '编辑器',
14+
},
15+
},
16+
17+
routes: [
18+
{
19+
path: '/markdown',
20+
name: 'MarkdownDemo',
21+
component: () => import('/@/views/demo/editor/Markdown.vue'),
22+
meta: {
23+
title: 'markdown编辑器',
24+
},
25+
},
26+
],
27+
} as AppRouteModule;

src/views/demo/editor/Markdown.vue

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<template>
2+
<div class="p-4">
3+
<a-button @click="toggleTheme" class="mb-2" type="primary">黑暗主题</a-button>
4+
<MarkDown v-model:value="value" ref="markDownRef" />
5+
</div>
6+
</template>
7+
<script lang="ts">
8+
import { defineComponent, ref, unref } from 'vue';
9+
import { MarkDown, MarkDownActionType } from '/@/components/Markdown';
10+
export default defineComponent({
11+
components: { MarkDown },
12+
setup() {
13+
const markDownRef = ref<Nullable<MarkDownActionType>>(null);
14+
const valueRef = ref(`
15+
# title
16+
17+
# content
18+
`);
19+
20+
function toggleTheme() {
21+
const markDown = unref(markDownRef);
22+
if (!markDown) return;
23+
const vditor = markDown.getVditor();
24+
vditor.setTheme('dark');
25+
}
26+
return {
27+
value: valueRef,
28+
toggleTheme,
29+
markDownRef,
30+
};
31+
},
32+
});
33+
</script>

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,6 +2346,11 @@ detect-indent@6.0.0:
23462346
resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd"
23472347
integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==
23482348

2349+
diff-match-patch@^1.0.5:
2350+
version "1.0.5"
2351+
resolved "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
2352+
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
2353+
23492354
diff@^4.0.1:
23502355
version "4.0.2"
23512356
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -6980,6 +6985,13 @@ vary@^1.1.2:
69806985
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
69816986
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
69826987

6988+
vditor@^3.5.5:
6989+
version "3.5.5"
6990+
resolved "https://registry.npmjs.org/vditor/-/vditor-3.5.5.tgz#03b7c965470fd434cd098e3f6ac6c7e65ca5a52a"
6991+
integrity sha512-NpBa0c1tK3jnH/E+rWkDO2x/bDx33KIWuThjF70gING58zuluxicGczuVb2KvdLxWoozJ6MaH5DQjj66Jct1QA==
6992+
dependencies:
6993+
diff-match-patch "^1.0.5"
6994+
69836995
vfile-location@^3.0.0:
69846996
version "3.1.0"
69856997
resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-3.1.0.tgz#81cd8a04b0ac935185f4fce16f270503fc2f692f"

0 commit comments

Comments
 (0)