tui-editor编辑器自定义按钮

tui-editor编辑器自定义按钮

上传图片 按钮及事件

<input ref="image" style="display:none;" type="file" accept="image/*" @change="uploadImage">
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())	
  })
  //获取菜单栏
  const toolbar = this.editor.getUI().getToolbar()
  
  //图片上传按钮及事件
  const imageDom = this.$refs.image
  this.editor.eventManager.addEventType('uploadEvent')
  this.editor.eventManager.listen('uploadEvent', ()=>{
    imageDom.click()
  })
  toolbar.insertItem(15, {
    type: 'button',
    options: {
	  className: 'el-icon-picture',
	  event: 'uploadEvent',
	  tooltip: '插入图片',
	  text:'',
	  style: 'font-size:14px;color:#000;background:none'
    }
  })
}
//图片上传
uploadImage(e){
  const target = e.target
  const file = target.files[0]
  const formdata = new FormData()
  formdata.append('file', file)
  uploadImageFile(formdata).then((res)=>{  //调接口
    if(res.success){
      const imgUrl = res.url
      this.addImgToMd(imgUrl, filename)
    }
  })
  target.value = ''  //清除数据
},
//添加图片到编辑器中
addImgToMd(data, imgname){
  const editor = this.editor.getCodeMirror()
  const editorHtml = this.editor.getCurrentModeEditor()
  const isMarkdownMode = this.editor.isMarkdownMode()
  if(isMarkdownMode){
    editor.replaceSelection(`![${imgname}](${data})`)
  } else {
    const range = editorHtml.getRange()
    const img = document.createElement('img')
    img.src = `${data}`
    img.alt = `${imgname}`
    range.insertNode(img)
  }
}

导入文件按钮及事件

<input ref="file" style="display:none;" type="file" accept=".md" @change="uploadFile">
  //导入文件按钮及事件
  const fileDom = this.$refs.file
  this.editor.eventManager.addEventType('uploadFileEvent')
  this.editor.eventManager.listen('uploadFileEvent', ()=>{
    fileDom.click()
  })
  toolbar.insertItem(23, {
    type: 'button',
    options: {
	  className: 'el-icon-upload',
	  event: 'uploadFileEvent',
	  tooltip: '导入md文件',
	  text:'',
	  style: 'font-size:14px;color:#000;background:none'
    }
  })
uploadFile(e){
  const target = e.target
  const file = target.files[0]
  const reader = new FileReader()
  const that = this
  reader.onload = function(evt) {
    that.setValue(evt.target.result)  //向编辑器传值
  }
  reader.readAsText(file)
}

导出文件按钮及事件

  //导出文件按钮及事件
  this.editor.eventManager.addEventType('exportFileEvent')
  this.editor.eventManager.listen('exportFileEvent', ()=>{
    const md = this.editor.getValue()
    //获取当前日期
    const date = new Date()
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const today = year + '-' + month + '-' + day
    this.exportFile(md, today + '.md')  //不加后缀,默认为txt文件
  })
  toolbar.insertItem(24, {
    type: 'button',
    options: {
	  className: 'el-icon-download',
	  event: 'exportFileEvent',
	  tooltip: '导出md文件',
	  text:'',
	  style: 'font-size:14px;color:#000;background:none'
    }
  })
//导出文件
exportFile(content, filename){
  const linkNode = document.createElement('a')
  linkNode.download = filename
  linkNode.style.display = 'none'
  // 利用Blob对象将字符内容转变成二进制数据
  var blob = new Blob([content])
  linkNode.href = URL.createObjectURL(blob)
  // 触发点击
  document.body.appendChild(linkNode)
  linkNode.click()
  // 移除
  document.body.removeChild(linkNode)
}

完整代码

<template>
  <div>
    <div :id="id" />
    <input ref="image" style="display:none;" type="file" accept="image/*" @change="uploadImage">
    <input ref="file" style="display:none;" type="file" accept=".md" @change="uploadFile">
  div>
template>

<script>
// 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 '@/components/MarkdownEditor/default-options'

// 自定义图片上传地址
import { uploadDescriptionFile } from '@/api/document'

export default {
  name: 'MarddownEditor',
  props: {
    value: {
      type: String,
      default: ''
    },
    id: {
      type: String,
      required: false,
      default() {
        return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
      }
    },
    options: {
      type: Object,
      default() {
        return defaultOptions
      }
    },
    mode: {
      type: String,
      default: 'markdown'
    },
    height: {
      type: String,
      required: false,
      default: '300px'
    },
    language: {
      type: String,
      required: false,
      default: 'zh_CN' // https://github.com/nhnent/tui.editor/tree/master/src/js/langs
    }
  },
  data() {
    return {
      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(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.initEditor()
  },
  destroyed() {
    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())
      })
      /*
      * 添加自定义按钮
      * */
      // 获取编辑器上的功能条,即菜单栏
      const toolbar = this.editor.getUI().getToolbar()
      const imageDom = this.$refs.image
      // 添加图片上传事件
      this.editor.eventManager.addEventType('uploadEvent')
      this.editor.eventManager.listen('uploadEvent', () => {
        imageDom.click()
      })
      // 添加自定义按钮
      toolbar.insertItem(15, {
        type: 'button',
        options: {
          className: 'el-icon-picture',
          event: 'uploadEvent',
          tooltip: '插入图片',
          text: '',
          style: 'font-size:14px;color:#000;background:none;'
        }
      })
      // 导入文件按钮
      const fileDom = this.$refs.file
      this.editor.eventManager.addEventType('importfileEvent')
      this.editor.eventManager.listen('importfileEvent', () => {
        fileDom.click()
      })
      toolbar.insertItem(23, {
        type: 'button',
        options: {
          className: 'el-icon-upload2',
          event: 'importfileEvent',
          tooltip: '导入md文件',
          text: '',
          style: 'font-size:14px;color:#000;background:none;'
        }
      })
      // 添加保存文档事件
      // this.editor.eventManager.addEventType('saveEvent')
      // this.editor.eventManager.listen('saveEvent', () => {
      //   this.$emit('save')
      // })
      // toolbar.insertItem(22, {
      //   type: 'button',
      //   options: {
      //     className: 'el-icon-s-claim',
      //     event: 'saveEvent',
      //     tooltip: '保存文档',
      //     text: '',
      //     style: 'font-size:14px;color:#000;background:none;'
      //   }
      // })
      // 导出md文件按钮
      this.editor.eventManager.addEventType('exportEvent')
      this.editor.eventManager.listen('exportEvent', () => {
        const md = this.editor.getValue()
        // 获取当前日期
        const date = new Date()
        const year = date.getFullYear()
        const month = date.getMonth() + 1
        const day = date.getDate()
        const today = year + '-' + month + '-' + day
        this.downloadF(md, today + '.md') // 不加后缀,默认是txt格式
      })
      toolbar.insertItem(24, {
        type: 'button',
        options: {
          className: 'el-icon-download',
          event: 'exportEvent',
          tooltip: '导出md文件',
          text: '',
          style: 'font-size:14px;color:#000;background:none;'
        }
      })
    },
    downloadF(content, filename) {
      const linkNode = document.createElement('a')
      linkNode.download = filename
      linkNode.style.display = 'none'
      // 利用Blob对象将字符内容转变成二进制数据
      const blob = new Blob([content])
      linkNode.href = URL.createObjectURL(blob)
      // 点击
      document.body.appendChild(linkNode)
      linkNode.click()
      // 移除
      document.body.removeChild(linkNode)
    },
    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()
    },
    /*
    * 自定义图片上传
    * */
    uploadImage(e) {
      const target = e.target
      const file = target.files[0]
      const formdata = new FormData()
      formdata.append('file', file)
      uploadDescriptionFile(formdata).then((res) => {
        if (res.success) {
          const imgUrl = res.url
          this.addImgToMd(imgUrl, file.name)
        }
      }).catch(error => {
        this.$message.error(error.msg)
      })
      target.value = '' // 清除数据
    },
    //  添加图片到markdown
    addImgToMd(data, imgname) {
      const editor = this.editor.getCodeMirror()
      const editorHtml = this.editor.getCurrentModeEditor()
      const isMarkdownMode = this.editor.isMarkdownMode()
      if (isMarkdownMode) {
        editor.replaceSelection(`![${imgname}](${data})`)
      } else {
        const range = editorHtml.getRange()
        const img = document.createElement('img')
        img.src = `${data}`
        img.alt = `${imgname}`
        range.insertNode(img)
      }
    },
    // 导入md文件
    uploadFile(e) {
      const target = e.target
      const file = target.files[0]
      var reader = new FileReader()
      const that = this
      reader.onload = function(evt) {
        that.setValue(evt.target.result)// 向编辑器传值
      }
      reader.readAsText(file)
    }
  }
}
script>
<style lang="scss">
.tui-tooltip{
  z-index:9999
}
style>

你可能感兴趣的:(vue,编辑器,javascript,前端)