首页 > 其他分享 >vue tinymce富文本编辑器封装

vue tinymce富文本编辑器封装

时间:2022-12-05 18:24:59浏览次数:60  
标签:文本编辑 vue const tinymce file plugins import type

<template>
  <div style="position: relative;">
    <div style="text-align: right; margin-bottom: 20px;">
      <el-popover
        placement="right"
        width="490"
        class="popoverbtn"
        trigger="click"
        @show="showData">
        <div class="popCon">
          <div class="poptop">
            <el-button
              v-for=" item in popData"
              :key="item"
              type="primary"
              class="spanDel"
              size="mini"
              plain
              @click="popClick(item)">{{ item.tempKey }}<i class="el-icon-delete" @click.stop.prevent="delPop(item)"/></el-button>
          </div>
          <div class="popbtm">
            <el-form ref="formInlineres" :inline="true" :rules="formInlinerules" :model="formInline" class="demo-form-inline">
              <el-form-item label="名称" prop="tempKey">
                <el-input v-model="formInline.tempKey" size="mini" placeholder="请输入名称"/>
              </el-form-item>
              <el-form-item label="值" prop="tempValue">
                <el-input v-model="formInline.tempValue" size="mini" placeholder="请输入值"/>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" size="mini" @click="onSubmit">添加</el-button>
              </el-form-item>
            </el-form>
          </div>
        </div>
        <el-button slot="reference" type="primary" icon="el-icon-edit" circle/>
      </el-popover>
      <el-upload
        ref="fileRefs"
        :before-upload="beforeUpload"
        :show-file-list="false"
        :disabled="disabled"
        class="uploadBtn"
        style="display:none"
        action=""
        accept=".docx"
      >
        <el-button :disabled="disabled">导入</el-button>
      </el-upload>
    </div>

    <editor v-model="content" :init="init" :disabled="disabled" @onClick="onClick"/>

  </div>
</template>

<script>
import 'mammoth/mammoth.browser.js'
import Mammoth from 'mammoth'
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver'
import 'tinymce/icons/default/icons'
import 'tinymce/themes/silver'
import 'tinymce/plugins/image'
import 'tinymce/plugins/media'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/code'
import 'tinymce/plugins/link'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/codesample'
import 'tinymce/plugins/hr'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/textpattern'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/template'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/imagetools'
import 'tinymce/plugins/autosave'
import 'tinymce/plugins/autoresize'
import {
  tempLabelqueryAll,
  tempLabelinsert,
  popremove
} from '@/api/tempmanage/mbglMbdz'
// import { uploadFile } from '@/api/system/upload'
// 扩展插件
// import "../assets/tinymce/plugins/lineheight/plugin";
export default {
  // name: 'imcoder-tinymce',
  components: {
    Editor
  },
  props: {
    value: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    plugins: {
      type: [String, Array],
      default:
          'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr nonbreaking insertdatetime advlist lists wordcount imagetools textpattern autosave bdmap autoresize lineheight'
    },
    toolbar: {
      type: [String, Array],
      default:
          'code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link codesample | alignleft aligncenter alignright alignjustify outdent indent lineheight formatpainter | \      styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \      table image media charmap hr pagebreak insertdatetime | bdmap fullscreen preview| importbtn'
    }
  }, data() {
    return {
      // 初始化配置
      init: {
        _target: () => this,
        language_url: '/static/langs/zh_CN.js',
        language: 'zh_CN',
        skin_url: '/static/skins/ui/oxide',
        height: 770,
        min_height: 770,
        max_height: 770,
        toolbar_mode: 'wrap',
        plugins: this.plugins,
        toolbar: this.toolbar,
        content_style: 'p {margin: 5px 0;}',
        fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
        font_formats:
            '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',
        branding: false,
        setup: (editor) => {
          const _this = this
          editor.ui.registry.addButton('importbtn', {
            text: '导入word',
            // icon:'material',
            onAction: function() {
              console.log('选择文本')
              _this.$refs['fileRefs'].$refs['upload-inner'].handleClick()
            }
          })
        },
        paste_data_images: true,
        // 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,
        // 如需ajax上传可参考https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_handler
        file_picker_callback: function(callback, value, meta) {
          // 文件分类
          let filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'
          // 为不同插件指定文件类型及后端地址
          switch (meta.filetype) {
            case 'image':
              filetype = '.jpg, .jpeg, .png, .gif'
              break
            case 'media':
              filetype = '.mp3, .mp4'
              break
            case 'file':
            default:
          }
          // 模拟出一个input用于添加本地文件
          const input = document.createElement('input')
          input.setAttribute('type', 'file')
          input.setAttribute('accept', filetype)
          input.click()
          input.onchange = function() {
            const file = this.files[0]
            const formData = new FormData()
            formData.append('file', file, file.name)
            // xhr.send(formData);
            // uploadFile(formData).then(response=>{
            //   callback('http://10.50.0.174:8091'+response.data.network);
            // })
          }
        }
      },
      content: this.value,
      popData: [],
      formInline: {
        tempKey: '',
        tempValue: ''
      },
      formInlinerules: {
        tempKey: [{
          required: true,
          message: '名称不能为空',
          trigger: 'blur'
        }],
        tempValue: [{
          required: true,
          message: '值不能为空',
          trigger: 'blur'
        }]
      }
    }
  },
  watch: {
    value(newValue) {
      // console.log(newValue)
      this.content = newValue
    },
    content(newValue) {
      // console.log('11')
      // console.log(newValue)
      this.$emit('input', newValue)
    }
  },
  mounted() {
    tinymce.init({})
  },
  methods: {
    beforeUpload(file) {
      const self = this
      var reader = new FileReader()
      reader.onloadend = function(event) {
        console.log(event)
        const arrayBuffer = reader.result
        // 将word 转换成html
        const loading = self.$loading({
          lock: true,
          text: '文件解析中....',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.3)'
        })
        Mammoth.convertToHtml({ arrayBuffer: arrayBuffer }).then(function(
          resultObject
        ) {
          // 重要!不适用setTimeout,无法使用
          setTimeout(() => {
            // 获取原来编辑器的内容
            const content = tinymce.activeEditor.getContent() + resultObject.value
            tinymce.activeEditor.setContent(content)
            loading.close()
          }, 100)
        })
      }
      reader.readAsArrayBuffer(file)
      return false
    },
    // 模块信息添加
    onSubmit() {
      if (this.formInline.tempKey && this.formInline.tempValue) {
        tempLabelinsert(this.formInline).then(res => {
          this.formInline.tempKey = ''
          this.formInline.tempValue = ''
          this.popQuery()
          this.$message({
            type: 'success',
            message: '添加成功'
          })
        })
      } else {
        this.$message({
          type: 'warning',
          message: '名称和值不能为空'
        })
      }
    },
    // 模块信息插入
    popClick(item) {
      const text = item.tempValue
      // 获取编辑器对象
      // eslint-disable-next-line no-undef
      tinyMCE.execCommand('mceInsertContent', false, text)
    },
    showData() {
      const _this = this
      tempLabelqueryAll().then(res => {
        console.log(res)
        _this.popData = res.data.data
      })
    },
    delPop(item) {
      this.$confirm('确定将选择数据删除?', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          return popremove(item.id)
        })
        .then(() => {
          this.showData()
          this.$message({
            type: 'error',
            message: '已删除!'
          })
        })
    }
  }
}
</script>

<style lang="scss" scoped>
  #textAreaTemplate {
  .uploadBtn {
    display: inline-block;
    margin: 0 10px;
  }
  .tabTiyle {
    border-left: 8px solid rgba(36, 145, 255, 1);
    padding-left: 15px;
    font-size: 21px;
    text-align: left;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: rgba(0, 0, 0, 0.87);
  }
  }
</style>
<style lang="scss" scoped>
  .dialog {
    text-align: left;
  }
  /deep/ .popoverbtn{
    position: absolute;
    z-index: 1000;
    right: 6px;
    top: 4px;
  }
  .spanDel{
  position: relative;
  .el-icon-delete{
    position: absolute;
    top: -5px;
    right: -5px;
    background: red;
    display: none;
    z-index: 9999999;
  }
}
.spanDel:hover .el-icon-delete{
  display: block;
}
.popCon{
  display: flex;
  height: 300px;
  flex-flow: column;
}
.poptop{
  flex: 5;
}
.popbtm{
  flex: 1;
}
/deep/ .el-button--mini, .el-button--mini.is-round{
  margin: 1%;
}
/deep/ .ql-editor{
  padding: 0!important;
}
</style>

 

标签:文本编辑,vue,const,tinymce,file,plugins,import,type
From: https://www.cnblogs.com/hged/p/16953078.html

相关文章