Files
Vue-Components-Library/TinymceEditor
jiulinxiri c41bfd0c73 富文本编辑器
富文本编辑器
2022-03-10 09:50:21 +08:00
..
2022-03-10 09:50:21 +08:00
2022-03-10 09:50:21 +08:00

项目更换富文本编辑器

项目的富文本编辑器 vue-quill-editor 目前不支持表格,决定更换为 tinymce 编辑器。

项目当前环境

项目当前的环境为 Vue 2.6.11 ,需要的版本

{
  "tinymce": "^5.4.2",
  "@tinymce/tinymce-vue": "^3.2.2",
}

配置安装

安装依赖

输入以下的命令,进行依赖的安装

npm install tinymce@5.4.2
npm install @tinymce/tinymce-vue@3.2.2

安装汉化包

点击进入汉化包下载页面

Jiulinxiri_20220307103321

将解压的文件放在 public 文件夹

Jiulinxiri_20220307103322

配置使用

封装后的 tinymce-editor.vue文件内容如下

<template>
  <div class="tinymce">
    <editor
        v-model="myValue"
        :id="id"
        :disabled="disabled"
        :init="editorInit"
        output-format="html"
    />
  </div>
</template>

<script>

// 引入组件
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/icons/default/icons' // 解决了icons.js 报错Unexpected token '<'
// 引入富文本编辑器主题的js和css
import 'tinymce/themes/silver/theme.min.js'
import 'tinymce/skins/ui/oxide/skin.min.css'
// 扩展插件
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/image'
import 'tinymce/plugins/code'
import 'tinymce/plugins/table'
import 'tinymce/plugins/wordcount'

export default {
  name: "tinymce-editor",
  components: {
    Editor
  },
  props: {
    id: {
      type: String,
      default: 'tinymceEditor'
    },
    value: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 编辑器初始化配置
      editorInit: {
        selector: '#tinymce', // 容器
        language_url: '/tinymce/langs/zh_CN.js',
        language: 'zh_CN',
        skin_url: '/tinymce/skins/ui/oxide', // 主题
        height: 300,
        plugins: 'link lists image table wordcount', // 用到的插件:链接、列表、图片、代码块、表格、字数
        toolbar: 'bold italic underline | subscript superscript | formatselect fontsizeselect | forecolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | link unlink table image| removeformat',
        toolbar_mode: 'wrap',
        fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
        setup: function(editor) {
          editor.on('init', function() {
            this.getBody().style.fontSize = '14px';
          });
        },
        // 工具栏
        images_upload_base_path: 'http://file.ourhonour.cn', // 上传图片基础路径
        images_upload_url: 'http://api.bjmcc.ourhonour.cn/zjzk/file/uploadImageLocation', // 上传图片地址
        // images_upload_handler: (blobInfo, success, failure) => { // 图片上传
        //   console.log(blobInfo, success, failure, '上传图片====--==-')
        //   const img = `data:${blobInfo.blob().type};base64,${blobInfo.base64()}`
        //   success(img)
        //   // this.handleImgUpload(blobInfo, success, failure)
        // },
        // forced_root_block : false,
        statusbar: false, // 底部的状态栏
        menubar: false, // 最上方的菜单
        branding: false, // 水印“Powered by TinyMCE”
        max_height: 500,
        min_height: 300
      },
      myValue: this.value
    }
  },
  mounted() {
    tinymce.init({})
  },
  methods: {
    handleChange(e, editor) {
      console.log(this.tinymceHtml)
      this.$emit('editorChange', e, editor)
    }
  },
  watch: {
    value(newValue) {
      this.myValue = newValue
    },
    myValue(newValue) {
      this.$emit('input', this.id, newValue)
    }
  }
}
</script>

<style lang="scss" scoped>
.TinyMCE {
  .preview {
    min-height: 200px;
    max-height: 400px;
    font-size: 14px;
    overflow-y: auto;
    margin: 25px auto;
    border: 1px solid #ccc;
    word-wrap: break-word;
  }
}
// 解决菜单下拉选项不显示的问题
.tox-tinymce-aux {
  z-index: 19891015 !important;
}
</style>

父组件使用的方式

<tinymce-editor 
    @input="editorChange" 
    id="achievements" 
    :disabled="false"  
    v-mode="form.achievements">
</tinymce-editor>

后台上传图片接口

/**
 * 上传图片方法
 * @param multipartFile
 * @param request
 * @return
 */
@PostMapping("/uploadImageLocation")
@ResponseBody
public FileDTO uploadImageLocation(@RequestParam(value = "file") MultipartFile multipartFile, HttpServletRequest request) {
    FileDTO fileDTO = new FileDTO();
    String path = "";
    try {
        path = fdfsClientUtils.upload(multipartFile);
        fileDTO.setLocation(path);
    } catch (Exception e) {
    }
    return fileDTO;
}

// FileDTO.java
package cn.ourhonour.modules.file.dto;

import lombok.Data;

@Data
public class FileDTO {
    private String location;
}