add tui.editor (#1374)
This commit is contained in:
		@@ -43,7 +43,6 @@
 | 
			
		||||
    "echarts": "4.1.0",
 | 
			
		||||
    "element-ui": "2.4.6",
 | 
			
		||||
    "file-saver": "1.3.8",
 | 
			
		||||
    "font-awesome": "4.7.0",
 | 
			
		||||
    "js-cookie": "2.2.0",
 | 
			
		||||
    "jsonlint": "1.6.3",
 | 
			
		||||
    "jszip": "3.1.5",
 | 
			
		||||
@@ -52,8 +51,8 @@
 | 
			
		||||
    "path-to-regexp": "2.4.0",
 | 
			
		||||
    "screenfull": "3.3.3",
 | 
			
		||||
    "showdown": "1.8.6",
 | 
			
		||||
    "simplemde": "1.11.2",
 | 
			
		||||
    "sortablejs": "1.7.0",
 | 
			
		||||
    "tui-editor": "1.2.7",
 | 
			
		||||
    "vue": "2.5.17",
 | 
			
		||||
    "vue-count-to": "1.0.13",
 | 
			
		||||
    "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>
 | 
			
		||||
  <div :style="{height:height+'px',zIndex:zIndex}" class="simplemde-container">
 | 
			
		||||
    <textarea :id="id"/>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div :id="id"/>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import 'font-awesome/css/font-awesome.min.css'
 | 
			
		||||
import 'simplemde/dist/simplemde.min.css'
 | 
			
		||||
import SimpleMDE from 'simplemde'
 | 
			
		||||
// deps for editor
 | 
			
		||||
import 'codemirror/lib/codemirror.css' // codemirror
 | 
			
		||||
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 {
 | 
			
		||||
  name: 'SimplemdeMd',
 | 
			
		||||
  name: 'MarddownEditor',
 | 
			
		||||
  props: {
 | 
			
		||||
    value: {
 | 
			
		||||
      type: String,
 | 
			
		||||
@@ -19,105 +21,98 @@ export default {
 | 
			
		||||
    id: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      required: false,
 | 
			
		||||
      default: 'markdown-editor-' + +new Date()
 | 
			
		||||
      default() {
 | 
			
		||||
        return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    autofocus: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    options: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default() {
 | 
			
		||||
        return defaultOptions
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    placeholder: {
 | 
			
		||||
    mode: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
      default: 'markdown'
 | 
			
		||||
    },
 | 
			
		||||
    height: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 150
 | 
			
		||||
      type: String,
 | 
			
		||||
      required: false,
 | 
			
		||||
      default: '300px'
 | 
			
		||||
    },
 | 
			
		||||
    zIndex: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 10
 | 
			
		||||
    },
 | 
			
		||||
    toolbar: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: function() {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
    language: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      required: false,
 | 
			
		||||
      default: 'en_US' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      simplemde: null,
 | 
			
		||||
      hasChange: false
 | 
			
		||||
      editor: null
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    editorOptions() {
 | 
			
		||||
      const options = Object.assign({}, defaultOptions, this.options)
 | 
			
		||||
      options.initialEditType = this.mode
 | 
			
		||||
      options.height = this.height
 | 
			
		||||
      options.language = this.language
 | 
			
		||||
      return options
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    value(val) {
 | 
			
		||||
      if (val === this.simplemde.value() && !this.hasChange) return
 | 
			
		||||
      this.simplemde.value(val)
 | 
			
		||||
    value(newValue, preValue) {
 | 
			
		||||
      if (newValue !== preValue && newValue !== this.editor.getValue()) {
 | 
			
		||||
        this.editor.setValue(newValue)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    language(val) {
 | 
			
		||||
      this.destroyEditor()
 | 
			
		||||
      this.initEditor()
 | 
			
		||||
    },
 | 
			
		||||
    height(newValue) {
 | 
			
		||||
      this.editor.height(newValue)
 | 
			
		||||
    },
 | 
			
		||||
    mode(newValue) {
 | 
			
		||||
      this.editor.changeMode(newValue)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.simplemde = new SimpleMDE({
 | 
			
		||||
      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())
 | 
			
		||||
    })
 | 
			
		||||
    this.initEditor()
 | 
			
		||||
  },
 | 
			
		||||
  destroyed() {
 | 
			
		||||
    this.simplemde.toTextArea()
 | 
			
		||||
    this.simplemde = null
 | 
			
		||||
    this.destroyEditor()
 | 
			
		||||
  },
 | 
			
		||||
  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>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
  <div class="components-container">
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
    </code>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
    <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>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@@ -17,32 +42,46 @@
 | 
			
		||||
import MarkdownEditor from '@/components/MarkdownEditor'
 | 
			
		||||
 | 
			
		||||
const content = `
 | 
			
		||||
**this is test**
 | 
			
		||||
**This is test**
 | 
			
		||||
 | 
			
		||||
* vue
 | 
			
		||||
* element
 | 
			
		||||
* webpack
 | 
			
		||||
 | 
			
		||||
## Simplemde
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'MarkdownDemo',
 | 
			
		||||
  components: { MarkdownEditor },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      content: content,
 | 
			
		||||
      html: ''
 | 
			
		||||
      html: '',
 | 
			
		||||
      languageTypeList: {
 | 
			
		||||
        'en': 'en_US',
 | 
			
		||||
        'zh': 'zh_CN',
 | 
			
		||||
        'es': 'es_ES'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    language() {
 | 
			
		||||
      return this.languageTypeList[this.$store.getters.language]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    markdown2Html() {
 | 
			
		||||
      import('showdown').then(showdown => {
 | 
			
		||||
        const converter = new showdown.Converter()
 | 
			
		||||
        this.html = converter.makeHtml(this.content)
 | 
			
		||||
      })
 | 
			
		||||
    getHtml() {
 | 
			
		||||
      this.html = this.$refs.markdownEditor.getHtml()
 | 
			
		||||
      console.log(this.html)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.editor-container{
 | 
			
		||||
  margin-bottom: 30px;
 | 
			
		||||
}
 | 
			
		||||
.tag-title{
 | 
			
		||||
  margin-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user