Skip to content

Commit a6c8e1a

Browse files
authored
add tui.editor (PanJiaChen#1374)
1 parent 929a4fc commit a6c8e1a

File tree

4 files changed

+166
-102
lines changed

4 files changed

+166
-102
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
"echarts": "4.1.0",
4444
"element-ui": "2.4.6",
4545
"file-saver": "1.3.8",
46-
"font-awesome": "4.7.0",
4746
"js-cookie": "2.2.0",
4847
"jsonlint": "1.6.3",
4948
"jszip": "3.1.5",
@@ -52,8 +51,8 @@
5251
"path-to-regexp": "2.4.0",
5352
"screenfull": "3.3.3",
5453
"showdown": "1.8.6",
55-
"simplemde": "1.11.2",
5654
"sortablejs": "1.7.0",
55+
"tui-editor": "1.2.7",
5756
"vue": "2.5.17",
5857
"vue-count-to": "1.0.13",
5958
"vue-i18n": "7.3.2",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// doc: https://nhnent.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor
2+
export default {
3+
minHeight: '200px',
4+
previewStyle: 'vertical',
5+
useCommandShortcut: true,
6+
useDefaultHTMLSanitizer: true,
7+
usageStatistics: false,
8+
hideModeSwitch: false,
9+
toolbarItems: [
10+
'heading',
11+
'bold',
12+
'italic',
13+
'strike',
14+
'divider',
15+
'hr',
16+
'quote',
17+
'divider',
18+
'ul',
19+
'ol',
20+
'task',
21+
'indent',
22+
'outdent',
23+
'divider',
24+
'table',
25+
'image',
26+
'link',
27+
'divider',
28+
'code',
29+
'codeblock'
30+
]
31+
}
Lines changed: 83 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<template>
2-
<div :style="{height:height+'px',zIndex:zIndex}" class="simplemde-container">
3-
<textarea :id="id"/>
4-
</div>
2+
<div :id="id"/>
53
</template>
64

75
<script>
8-
import 'font-awesome/css/font-awesome.min.css'
9-
import 'simplemde/dist/simplemde.min.css'
10-
import SimpleMDE from 'simplemde'
6+
// deps for editor
7+
import 'codemirror/lib/codemirror.css' // codemirror
8+
import 'tui-editor/dist/tui-editor.css' // editor ui
9+
import 'tui-editor/dist/tui-editor-contents.css' // editor content
10+
11+
import Editor from 'tui-editor'
12+
import defaultOptions from './defaultOptions'
1113
1214
export default {
13-
name: 'SimplemdeMd',
15+
name: 'MarddownEditor',
1416
props: {
1517
value: {
1618
type: String,
@@ -19,105 +21,98 @@ export default {
1921
id: {
2022
type: String,
2123
required: false,
22-
default: 'markdown-editor-' + +new Date()
24+
default() {
25+
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
26+
}
2327
},
24-
autofocus: {
25-
type: Boolean,
26-
default: false
28+
options: {
29+
type: Object,
30+
default() {
31+
return defaultOptions
32+
}
2733
},
28-
placeholder: {
34+
mode: {
2935
type: String,
30-
default: ''
36+
default: 'markdown'
3137
},
3238
height: {
33-
type: Number,
34-
default: 150
35-
},
36-
zIndex: {
37-
type: Number,
38-
default: 10
39+
type: String,
40+
required: false,
41+
default: '300px'
3942
},
40-
toolbar: {
41-
type: Array,
42-
default: function() {
43-
return []
44-
}
43+
language: {
44+
type: String,
45+
required: false,
46+
default: 'en_US' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs
4547
}
4648
},
4749
data() {
4850
return {
49-
simplemde: null,
50-
hasChange: false
51+
editor: null
52+
}
53+
},
54+
computed: {
55+
editorOptions() {
56+
const options = Object.assign({}, defaultOptions, this.options)
57+
options.initialEditType = this.mode
58+
options.height = this.height
59+
options.language = this.language
60+
return options
5161
}
5262
},
5363
watch: {
54-
value(val) {
55-
if (val === this.simplemde.value() && !this.hasChange) return
56-
this.simplemde.value(val)
64+
value(newValue, preValue) {
65+
if (newValue !== preValue && newValue !== this.editor.getValue()) {
66+
this.editor.setValue(newValue)
67+
}
68+
},
69+
language(val) {
70+
this.destroyEditor()
71+
this.initEditor()
72+
},
73+
height(newValue) {
74+
this.editor.height(newValue)
75+
},
76+
mode(newValue) {
77+
this.editor.changeMode(newValue)
5778
}
5879
},
5980
mounted() {
60-
this.simplemde = new SimpleMDE({
61-
element: document.getElementById(this.id),
62-
autoDownloadFontAwesome: false,
63-
autofocus: this.autofocus,
64-
toolbar: this.toolbar.length > 0 ? this.toolbar : undefined,
65-
spellChecker: false,
66-
insertTexts: {
67-
link: ['[', ']( )']
68-
},
69-
// hideIcons: ['guide', 'heading', 'quote', 'image', 'preview', 'side-by-side', 'fullscreen'],
70-
placeholder: this.placeholder
71-
})
72-
if (this.value) {
73-
this.simplemde.value(this.value)
74-
}
75-
this.simplemde.codemirror.on('change', () => {
76-
if (this.hasChange) {
77-
this.hasChange = true
78-
}
79-
this.$emit('input', this.simplemde.value())
80-
})
81+
this.initEditor()
8182
},
8283
destroyed() {
83-
this.simplemde.toTextArea()
84-
this.simplemde = null
84+
this.destroyEditor()
85+
},
86+
methods: {
87+
initEditor() {
88+
this.editor = new Editor({
89+
el: document.getElementById(this.id),
90+
...this.editorOptions
91+
})
92+
if (this.value) {
93+
this.editor.setValue(this.value)
94+
}
95+
this.editor.on('change', () => {
96+
this.$emit('input', this.editor.getValue())
97+
})
98+
},
99+
destroyEditor() {
100+
if (!this.editor) return
101+
this.editor.off('change')
102+
this.editor.remove()
103+
},
104+
setValue(value) {
105+
this.editor.setValue(value)
106+
},
107+
getValue() {
108+
return this.editor.getValue()
109+
},
110+
setHtml(value) {
111+
this.editor.setHtml(value)
112+
},
113+
getHtml() {
114+
return this.editor.getHtml()
115+
}
85116
}
86117
}
87118
</script>
88-
89-
<style scoped>
90-
.simplemde-container>>>.CodeMirror {
91-
min-height: 150px;
92-
line-height: 20px;
93-
}
94-
95-
.simplemde-container>>>.CodeMirror-scroll {
96-
min-height: 150px;
97-
}
98-
99-
.simplemde-container>>>.CodeMirror-code {
100-
padding-bottom: 40px;
101-
}
102-
103-
.simplemde-container>>>.editor-statusbar {
104-
display: none;
105-
}
106-
107-
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-link {
108-
color: #1890ff;
109-
}
110-
111-
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-string.cm-url {
112-
color: #2d3b4d;
113-
}
114-
115-
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-formatting-link-string.cm-url {
116-
padding: 0 2px;
117-
color: #E61E1E;
118-
}
119-
.simplemde-container >>> .editor-toolbar.fullscreen,
120-
.simplemde-container >>> .CodeMirror-fullscreen {
121-
z-index: 1003;
122-
}
123-
</style>
Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,87 @@
11
<template>
22
<div class="components-container">
3+
34
<code>Markdown is based on
4-
<a href="https://github.com/sparksuite/simplemde-markdown-editor" target="_blank">simplemde-markdown-editor</a> ,Simply encapsulated in Vue.
5+
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,Simply encapsulated in Vue.
56
<a target="_blank" href="https://juejin.im/post/593121aa0ce4630057f70d35#heading-15">
67
相关文章 </a>
78
</code>
9+
10+
<div class="editor-container">
11+
<el-tag class="tag-title">Basic:</el-tag>
12+
<markdown-editor v-model="content" height="300px"/>
13+
</div>
14+
15+
<div class="editor-container">
16+
<el-tag class="tag-title">Markdown Mode:</el-tag>
17+
<markdown-editor ref="markdownEditor" v-model="content" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px"/>
18+
</div>
19+
20+
<div class="editor-container">
21+
<el-tag class="tag-title">Customize Toolbar:</el-tag>
22+
<markdown-editor
23+
ref="markdownEditor"
24+
v-model="content"
25+
:options="{ toolbarItems: ['heading','bold','italic']}"
26+
/>
27+
</div>
28+
829
<div class="editor-container">
9-
<markdown-editor id="contentEditor" ref="contentEditor" v-model="content" :height="300" :z-index="20"/>
30+
<el-tag class="tag-title">I18n:</el-tag>
31+
<el-alert :closable="false" title="You can change the language of the admin system to see the effect" type="success"/>
32+
<markdown-editor v-model="content" :language="language" height="300px"/>
1033
</div>
11-
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="markdown2Html">To HTML</el-button>
34+
35+
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">Get HTML</el-button>
1236
<div v-html="html"/>
37+
1338
</div>
1439
</template>
1540

1641
<script>
1742
import MarkdownEditor from '@/components/MarkdownEditor'
1843
1944
const content = `
20-
**this is test**
45+
**This is test**
2146
2247
* vue
2348
* element
2449
* webpack
2550
26-
## Simplemde
2751
`
28-
2952
export default {
3053
name: 'MarkdownDemo',
3154
components: { MarkdownEditor },
3255
data() {
3356
return {
3457
content: content,
35-
html: ''
58+
html: '',
59+
languageTypeList: {
60+
'en': 'en_US',
61+
'zh': 'zh_CN',
62+
'es': 'es_ES'
63+
}
64+
}
65+
},
66+
computed: {
67+
language() {
68+
return this.languageTypeList[this.$store.getters.language]
3669
}
3770
},
3871
methods: {
39-
markdown2Html() {
40-
import('showdown').then(showdown => {
41-
const converter = new showdown.Converter()
42-
this.html = converter.makeHtml(this.content)
43-
})
72+
getHtml() {
73+
this.html = this.$refs.markdownEditor.getHtml()
74+
console.log(this.html)
4475
}
4576
}
4677
}
4778
</script>
4879

80+
<style scoped>
81+
.editor-container{
82+
margin-bottom: 30px;
83+
}
84+
.tag-title{
85+
margin-bottom: 5px;
86+
}
87+
</style>

0 commit comments

Comments
 (0)