forked from AkkomaGang/admin-fe
add tui.editor (#1374)
This commit is contained in:
parent
54dc9ddfaa
commit
b37a789f63
4 changed files with 166 additions and 102 deletions
|
@ -43,7 +43,6 @@
|
||||||
"echarts": "4.1.0",
|
"echarts": "4.1.0",
|
||||||
"element-ui": "2.4.6",
|
"element-ui": "2.4.6",
|
||||||
"file-saver": "1.3.8",
|
"file-saver": "1.3.8",
|
||||||
"font-awesome": "4.7.0",
|
|
||||||
"js-cookie": "2.2.0",
|
"js-cookie": "2.2.0",
|
||||||
"jsonlint": "1.6.3",
|
"jsonlint": "1.6.3",
|
||||||
"jszip": "3.1.5",
|
"jszip": "3.1.5",
|
||||||
|
@ -52,8 +51,8 @@
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"screenfull": "3.3.3",
|
"screenfull": "3.3.3",
|
||||||
"showdown": "1.8.6",
|
"showdown": "1.8.6",
|
||||||
"simplemde": "1.11.2",
|
|
||||||
"sortablejs": "1.7.0",
|
"sortablejs": "1.7.0",
|
||||||
|
"tui-editor": "1.2.7",
|
||||||
"vue": "2.5.17",
|
"vue": "2.5.17",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-i18n": "7.3.2",
|
"vue-i18n": "7.3.2",
|
||||||
|
|
31
src/components/MarkdownEditor/defaultOptions.js
Normal file
31
src/components/MarkdownEditor/defaultOptions.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// doc: https://nhnent.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor
|
||||||
|
export default {
|
||||||
|
minHeight: '200px',
|
||||||
|
previewStyle: 'vertical',
|
||||||
|
useCommandShortcut: true,
|
||||||
|
useDefaultHTMLSanitizer: true,
|
||||||
|
usageStatistics: false,
|
||||||
|
hideModeSwitch: false,
|
||||||
|
toolbarItems: [
|
||||||
|
'heading',
|
||||||
|
'bold',
|
||||||
|
'italic',
|
||||||
|
'strike',
|
||||||
|
'divider',
|
||||||
|
'hr',
|
||||||
|
'quote',
|
||||||
|
'divider',
|
||||||
|
'ul',
|
||||||
|
'ol',
|
||||||
|
'task',
|
||||||
|
'indent',
|
||||||
|
'outdent',
|
||||||
|
'divider',
|
||||||
|
'table',
|
||||||
|
'image',
|
||||||
|
'link',
|
||||||
|
'divider',
|
||||||
|
'code',
|
||||||
|
'codeblock'
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,16 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div :style="{height:height+'px',zIndex:zIndex}" class="simplemde-container">
|
<div :id="id"/>
|
||||||
<textarea :id="id"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import 'font-awesome/css/font-awesome.min.css'
|
// deps for editor
|
||||||
import 'simplemde/dist/simplemde.min.css'
|
import 'codemirror/lib/codemirror.css' // codemirror
|
||||||
import SimpleMDE from 'simplemde'
|
import 'tui-editor/dist/tui-editor.css' // editor ui
|
||||||
|
import 'tui-editor/dist/tui-editor-contents.css' // editor content
|
||||||
|
|
||||||
|
import Editor from 'tui-editor'
|
||||||
|
import defaultOptions from './defaultOptions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SimplemdeMd',
|
name: 'MarddownEditor',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -19,105 +21,98 @@ export default {
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'markdown-editor-' + +new Date()
|
default() {
|
||||||
|
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
autofocus: {
|
options: {
|
||||||
type: Boolean,
|
type: Object,
|
||||||
default: false
|
default() {
|
||||||
|
return defaultOptions
|
||||||
|
}
|
||||||
},
|
},
|
||||||
placeholder: {
|
mode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: 'markdown'
|
||||||
},
|
},
|
||||||
height: {
|
height: {
|
||||||
type: Number,
|
type: String,
|
||||||
default: 150
|
required: false,
|
||||||
|
default: '300px'
|
||||||
},
|
},
|
||||||
zIndex: {
|
language: {
|
||||||
type: Number,
|
type: String,
|
||||||
default: 10
|
required: false,
|
||||||
},
|
default: 'en_US' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs
|
||||||
toolbar: {
|
|
||||||
type: Array,
|
|
||||||
default: function() {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
simplemde: null,
|
editor: null
|
||||||
hasChange: false
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editorOptions() {
|
||||||
|
const options = Object.assign({}, defaultOptions, this.options)
|
||||||
|
options.initialEditType = this.mode
|
||||||
|
options.height = this.height
|
||||||
|
options.language = this.language
|
||||||
|
return options
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(val) {
|
value(newValue, preValue) {
|
||||||
if (val === this.simplemde.value() && !this.hasChange) return
|
if (newValue !== preValue && newValue !== this.editor.getValue()) {
|
||||||
this.simplemde.value(val)
|
this.editor.setValue(newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
language(val) {
|
||||||
|
this.destroyEditor()
|
||||||
|
this.initEditor()
|
||||||
|
},
|
||||||
|
height(newValue) {
|
||||||
|
this.editor.height(newValue)
|
||||||
|
},
|
||||||
|
mode(newValue) {
|
||||||
|
this.editor.changeMode(newValue)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.simplemde = new SimpleMDE({
|
this.initEditor()
|
||||||
element: document.getElementById(this.id),
|
|
||||||
autoDownloadFontAwesome: false,
|
|
||||||
autofocus: this.autofocus,
|
|
||||||
toolbar: this.toolbar.length > 0 ? this.toolbar : undefined,
|
|
||||||
spellChecker: false,
|
|
||||||
insertTexts: {
|
|
||||||
link: ['[', ']( )']
|
|
||||||
},
|
|
||||||
// hideIcons: ['guide', 'heading', 'quote', 'image', 'preview', 'side-by-side', 'fullscreen'],
|
|
||||||
placeholder: this.placeholder
|
|
||||||
})
|
|
||||||
if (this.value) {
|
|
||||||
this.simplemde.value(this.value)
|
|
||||||
}
|
|
||||||
this.simplemde.codemirror.on('change', () => {
|
|
||||||
if (this.hasChange) {
|
|
||||||
this.hasChange = true
|
|
||||||
}
|
|
||||||
this.$emit('input', this.simplemde.value())
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.simplemde.toTextArea()
|
this.destroyEditor()
|
||||||
this.simplemde = null
|
},
|
||||||
|
methods: {
|
||||||
|
initEditor() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
el: document.getElementById(this.id),
|
||||||
|
...this.editorOptions
|
||||||
|
})
|
||||||
|
if (this.value) {
|
||||||
|
this.editor.setValue(this.value)
|
||||||
|
}
|
||||||
|
this.editor.on('change', () => {
|
||||||
|
this.$emit('input', this.editor.getValue())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
destroyEditor() {
|
||||||
|
if (!this.editor) return
|
||||||
|
this.editor.off('change')
|
||||||
|
this.editor.remove()
|
||||||
|
},
|
||||||
|
setValue(value) {
|
||||||
|
this.editor.setValue(value)
|
||||||
|
},
|
||||||
|
getValue() {
|
||||||
|
return this.editor.getValue()
|
||||||
|
},
|
||||||
|
setHtml(value) {
|
||||||
|
this.editor.setHtml(value)
|
||||||
|
},
|
||||||
|
getHtml() {
|
||||||
|
return this.editor.getHtml()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.simplemde-container>>>.CodeMirror {
|
|
||||||
min-height: 150px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.CodeMirror-scroll {
|
|
||||||
min-height: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.CodeMirror-code {
|
|
||||||
padding-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.editor-statusbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-link {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-string.cm-url {
|
|
||||||
color: #2d3b4d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplemde-container>>>.CodeMirror .CodeMirror-code .cm-formatting-link-string.cm-url {
|
|
||||||
padding: 0 2px;
|
|
||||||
color: #E61E1E;
|
|
||||||
}
|
|
||||||
.simplemde-container >>> .editor-toolbar.fullscreen,
|
|
||||||
.simplemde-container >>> .CodeMirror-fullscreen {
|
|
||||||
z-index: 1003;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,15 +1,40 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
|
|
||||||
<code>Markdown is based on
|
<code>Markdown is based on
|
||||||
<a href="https://github.com/sparksuite/simplemde-markdown-editor" target="_blank">simplemde-markdown-editor</a> ,Simply encapsulated in Vue.
|
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,Simply encapsulated in Vue.
|
||||||
<a target="_blank" href="https://juejin.im/post/593121aa0ce4630057f70d35#heading-15">
|
<a target="_blank" href="https://juejin.im/post/593121aa0ce4630057f70d35#heading-15">
|
||||||
相关文章 </a>
|
相关文章 </a>
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<markdown-editor id="contentEditor" ref="contentEditor" v-model="content" :height="300" :z-index="20"/>
|
<el-tag class="tag-title">Basic:</el-tag>
|
||||||
|
<markdown-editor v-model="content" height="300px"/>
|
||||||
</div>
|
</div>
|
||||||
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="markdown2Html">To HTML</el-button>
|
|
||||||
|
<div class="editor-container">
|
||||||
|
<el-tag class="tag-title">Markdown Mode:</el-tag>
|
||||||
|
<markdown-editor ref="markdownEditor" v-model="content" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="editor-container">
|
||||||
|
<el-tag class="tag-title">Customize Toolbar:</el-tag>
|
||||||
|
<markdown-editor
|
||||||
|
ref="markdownEditor"
|
||||||
|
v-model="content"
|
||||||
|
:options="{ toolbarItems: ['heading','bold','italic']}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="editor-container">
|
||||||
|
<el-tag class="tag-title">I18n:</el-tag>
|
||||||
|
<el-alert :closable="false" title="You can change the language of the admin system to see the effect" type="success"/>
|
||||||
|
<markdown-editor v-model="content" :language="language" height="300px"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">Get HTML</el-button>
|
||||||
<div v-html="html"/>
|
<div v-html="html"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -17,32 +42,46 @@
|
||||||
import MarkdownEditor from '@/components/MarkdownEditor'
|
import MarkdownEditor from '@/components/MarkdownEditor'
|
||||||
|
|
||||||
const content = `
|
const content = `
|
||||||
**this is test**
|
**This is test**
|
||||||
|
|
||||||
* vue
|
* vue
|
||||||
* element
|
* element
|
||||||
* webpack
|
* webpack
|
||||||
|
|
||||||
## Simplemde
|
|
||||||
`
|
`
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MarkdownDemo',
|
name: 'MarkdownDemo',
|
||||||
components: { MarkdownEditor },
|
components: { MarkdownEditor },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
content: content,
|
content: content,
|
||||||
html: ''
|
html: '',
|
||||||
|
languageTypeList: {
|
||||||
|
'en': 'en_US',
|
||||||
|
'zh': 'zh_CN',
|
||||||
|
'es': 'es_ES'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
language() {
|
||||||
|
return this.languageTypeList[this.$store.getters.language]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
markdown2Html() {
|
getHtml() {
|
||||||
import('showdown').then(showdown => {
|
this.html = this.$refs.markdownEditor.getHtml()
|
||||||
const converter = new showdown.Converter()
|
console.log(this.html)
|
||||||
this.html = converter.makeHtml(this.content)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.editor-container{
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
.tag-title{
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue