Vue2 +TinyMCE 实现富文本编辑器

目录

0.版本

1.安装

2.创建本地服务

3.实现一个基础的tinymce编辑器

4.实现文件、图片和视频上传

0.准备工作

1.图片上传(点击图片图标的默认上传)

2.文件上传(包括图片,流媒体,附件)

3.媒体展示问题

5.powerpaste —— Microsoft word粘贴插件

1.插件使用

2.问题

结语


0.版本

vue@2.6.14

tinymce@5.1.0

@tinymce/tinymce-vue@3.0.1

因为是用的vue2,所以tinymce版本只能选择5.x,tinymce-vue选择对应3.x。

关于vue2,vue3怎么选择tinymce点击这里

1.安装

npm install tinymce@5.1.0 -S
npm install @tinymce/tinymce-vue@3.0.1

2.创建本地服务

使用npm安装的tinymce默认使用的是云服务,云服务是需要在官网注册获取api-key,如果没有api-key将无法使用你的富文本编辑器。所以选择本地创建服务。

1.找在node_models文件夹下找到tinymce文件夹,拷贝skins文件夹到 src/assets/tinymce文件夹下

(assets下的tinymce是自己创建的,图片中的media,powerpaste暂时不用管,构建一个编辑器的话这两个文件夹不需要,这两个文件夹是插件,后续会提到,assets存放这个库其实是不规范的,因为assets是存放一些静态资源的,但是这里为了方便就先存放到这里)

2.中文语言包,tinymce是国外的,默认使用的英文,所以要想编辑器中展示的是中文就需要下载中文语言包,及上图中assets/tinymce下的zh_CN.js。官网下载地址点击这里

3.实现一个基础的tinymce编辑器

使用以下代码,在components文件夹下或者其他地方创建一个tinymce编程器的组件,方便调用,一下代码是最基本的配置,能让你编辑器创建并且实现最基本的编辑需求。

<!-- tinymc富文本 -->
<template>
  <div>
    <editor
      v-model="myValue"
      :init="init"
      :disabled="disabled"
      @onClick="onClick"
    >
    </editor>
  </div>
</template>

<script>
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/skins/ui/oxide/skin.css";
import "@/assets/tinymce/zh_CN.js"; // 本地汉化
import "tinymce/themes/silver/theme";

//下面引入的都是tiny的插件,这些插件是免费的可以直接用你npm下载的包里的
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/link" //上传文件
// import "tinymce/icons/default"; // 图标 -解决测试环境找不icon问题
import "tinymce/plugins/autoresize"; // 自动调整大小
import 'tinymce/plugins/paste' // 粘贴


export default {
  name: "tinymce",
  components: {
    Editor,
  },
  props: {
    //传入一个value,使组件支持v-model绑定
    value: {
      type: String,
      default: "",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
//各种功能插件
    plugins: {
      type: [String, Array],
      default:
        'lists code pagebreak charmap emoticons save preview print image media link powerpaste paste' +
        'anchor codesample table wordcount fullscreen help searchreplace hr insertdatetime autoresize',
    },
//工具栏
    toolbar: {
      type: [String, Array],
      default:
      // 'undo redo | searchreplace | bold  italic | underline | strikethrough | alignleft  aligncenter alignright | outdent indent  blockquote  removeformat subscript superscript code codesample hr bullist numlist link image charmap preview anchor pagebreak insertdatetime  table  forecolor backcolor'
        "undo redo |  formatselect | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media link table | removeformat hr",
    },
  },
  data() {
    return {
      //初始化配置
      init: {
        language_url: "@/asset/tinymce/langs/zh_CN.js", // 这里需要单独处理
        language: "zh_CN",
        height: 500,
        width: "100%",
        plugins: this.plugins,
        toolbar: this.toolbar,
        branding: true,
        menubar: true,
        resize: true,
      },
      myValue: this.value,
    };
  },
  mounted() {
    tinymce.init({});
  },
  methods: {
    //添加相关的事件,可用的事件参照文档=> https://github.com/tinymce/tinymce-vue => All available events
    //需要什么事件可以自己增加
    onClick(e) {
      this.$emit("onClick", e, tinymce);
    },
    clear() {
      this.myValue = "";
    },
  },
  watch: {
    value(newValue) {
      this.myValue = newValue;
    },
    myValue(newValue) {
      this.$emit("input", newValue);
    },
  },
};
</script>
<style scoped></style>

以下是组件的应用,在你需要的页面应用该组件来创建一个编辑器。

<template>
    <div>
        <Tinymce :height="200" v-model="content"></Tinymce>
    </div>
</template>

<script>



</script>
export default {
    name: 'MyEditor',
    components: {Tinymce},
    data():{
        return:{
            content:''
        }
}

运行结果:(工具栏会根据你配置插件和toolbar改变)

到这里,就是tinymce最简单的应用。

4.实现文件、图片和视频上传

实现该功能的目的是为了让使用者在编辑器中插入文件、图片和视频的时候,就将插入的资源上传至服务器中保存下来,使得编辑器中的资源地址是上传到服务器之后的地址,一面出现资源丢失的情况。

0.准备工作

假设现在有一个服务端接口,用来接收前端上穿的资源,将资源上传到服务器中。如下:file是需要上传的文件的,sourceType是文件的类型,0:图片类型,1:流媒体类型,2:附件类型。该服务端接口就根据自己的项目需求来设计实现,本文主要讲的是tinymce,这里就不赘述。

 @ResponseBody
    @PostMapping("/save_rich_editor")
    public RichEditorResponseDto saveForRichEditor(
            @RequestParam(value = "file") MultipartFile multipartFile,
            @RequestParam(value = "sourceType") Integer sourceType) {
        return fileService.save(multipartFile, sourceType);
    }

1.图片上传(点击图片图标的默认上传)

方式1:使用tinymce默认的上传逻辑来处理,使用该方式来处理的话只需要在init中配置几个属性即可


init:{
    ...

    // 上传接口地址为:http://127.0.0.1:8080/biz/oms/file/save_rich_editor
    images_upload_url: '/biz/oms/file/save_rich_editor',
    images_upload_base_path: 'http://127.0.0.1:8080'

    // 上传时是否携带凭证,如cookie,authorization,headers,TLS client certificates
    images_upload_credentials: true

    ...
}

方式2:使用images_upload_handler上传,使用该方式上床,只需要在init中配置images_upload_handler属性即可,该方法可以自定义上传逻辑。

init:{
    ...

    images_upload_handler: function (blobInfo, success, failure) {
        let formData = new FormData()
        // 将文件数据放入file字段
        formData.append('file', blobInfo.blob())
        //文件类型放入sourceType字段
        formData.append('sourceType', SOURCE_TYPE.image.toString())

// 注意:在formData放入的数据,取决于后端接口需要的数据,以上是我后端接口需要的两个参数
        Api.uploadFile(formData).then(res => {
            console.log(res.data)
            if (res.data.errno === 0) {
                //上传成功用sucess函数解析url,success函数其他参数可自己查看官网或其他文档
                success(res.data.data.url)
            } else {
                //上传成功用failure函数返回
                failure("上传失败")
            }
        })
    },

    ...

}

2.文件上传(包括图片,流媒体,附件)

tinymce中有一个文件上传配置 file_picker_callback,配置后可直接上床不同类型的文件,定义自己的上传逻辑

在配置了这个属性后,上传功能会多出一个上床图标,如下图所示。

可以自行为这个上传图标创建一个类型为file的input标签,用来选择需要上传的文件,代码示例如下。

init:{
    ...

    file_picker_callback: function (callback, value, meta) {
          // 创建文件上传标签
          let input = document.createElement('input')
          input.setAttribute('type', 'file')
          let that = this
          // 选择后上传
          input.onchange = function () {
            console.log(this.files[0])
            let file = this.files[0]
            if (meta.filetype === 'image' && file.size > 1024 * 1024 * 10) {
              alert("图片过大!")
              return
            }
            if (meta.filetype === 'media' && file.size > 1024 * 1024 * 200) {
              alert("视频过大!")
              return
            }
            let formData = new FormData()
            formData.append('file', file)
            formData.append('sourceType', SOURCE_TYPE[meta.filetype].toString())
            Api.uploadFile(formData).then(res => {
              if (res.data.errno === 0) {
                callback(res.data.data.url)
              }
            })
          }
          input.click();
        },

     ...
}

3.媒体展示问题

我在运用的时候上床视频老是出现无法展示的问题,找了相关资料找到了几个方法,但只有一个方法成功:更改media插件文件。

不知道是bug还是什么原因,tinymce自己提供的media插中media_live_embaeds属性展示对视频无效,在网上我找到了一个最简单的方法,就是有大神自己修改了media插件并开源出来。

在assets/tinymce目录下创建一个media文件,在该文件中创建一个plugin.js的文件,内容如下(大神自己修改media插件)

点击跳转插件地址

 

选择自己适合的版本,运用此插件后,视频还是无法正常插入,需修改一下插件中的基础代码

取消注释,显示播放器:(解决插入的视频只是一个张图片的问题)

将ObjectSelected函数(图片中的函数)替换为代码中的函数:(解决选择视频时,下方重复出现该视频的问题)

    // editor.on('ObjectSelected', function (e) {
    //   var objectType = e.target.getAttribute('data-mce-object');
    //   if (objectType === 'audio' || objectType === 'script') {
    //     e.preventDefault();
    //   }
    // });
    editor.on('ObjectSelected', function (e) {
      var objectType = e.target.getAttribute('data-mce-object');
      if (objectType === 'audio' || objectType === 'video' || objectType === 'script') {
        e.preventDefault();
      }
    });

完成以上步骤视频因该可以正常播放。

5.powerpaste —— Microsoft word粘贴插件

1.插件使用

powerpaste是一款用于tinymce粘贴 Microsoft word文档的内容和格式的插件,官方的该插件不免费提供,所以我们可以自己放入项目中使用。

powerpaste插件下载地址

tinymce 大版本4,对应powerpaste-3.3.3-308, 大版本5对应4.0.1-317

下载插件后,同样将插件放入assets/tinymce文件夹下,如下图所示

放入插件后,在init配置项中配置一下属性:

init{
    ...
    // propmt站提示询问是否保留word格式,merge为自动保留word格式,clear为不保留word格式
    powerpaste_word_import: 'propmt', // 关于word格式粘贴配置,参数可以是propmt, merge, clear,效果自行切换对比
    powerpaste_html_import: 'propmt',// 关于html格式粘贴配置
    powerpaste_allow_local_images: true,


    // 添加扩展插件,将powerpaste作为外部插件引入
    external_plugins: {

        // 这里一定要写自己powerpaste中plugin.min.js的地址,写正确!
        powerpaste: '../../assets/tinymce/powerpaste/plugin.min.js'
    },


    ...
    
}

完成上述操作后,就可以运行查看

点击保留样式即可。

2.问题

项目完成到这一步后一切正常,但是下一步出现问题。当我点击保持样式后,他会弹窗提醒需要安装adobe flash player 的浏览器插件才可以粘贴Microsofte word文档中的图片,如下图所示。

此时如果点击关闭,将不会保留word格式,需要点击弹窗右上角叉号才会继续保留格式。

安装插件

在我安装好插件后,刷新再次粘贴,又出现了一下弹窗:

该弹窗的意思是按Ctrl + v 就可以粘贴word格式,但是我了对应键位之后没有反应,点击叉号还是只能保留格式,但图片还是没有粘贴成功。现在我使用的是edge浏览器,换了谷歌浏览器尝试结果相同。

结语

以上就是我对tinymce的应用以及遇到的问题。希望对大家有帮助,也希望有大神能帮助解决。

Vue2 Tinymce富文本编辑器是一种用于在Vue2项目中实现富文本编辑功能的插件。您可以按照以下步骤进行安装和使用: 1. 首先,您需要安装依赖。可以通过在终端中运行以下命令来安装依赖: ``` npm install tinymce ``` 2. 接下来,您需要将tinymce的skins文件夹复制到您的项目中。您可以在node_modules/tinymce目录下找到skins文件夹,并将其复制到您的src/assets/tinymce目录下。 3. 然后,您可以创建一个Tinymce.vue组件来封装Tinymce编辑器。可以根据您的需求进行自定义配置,***并将其放置在您的项目中。 5. 在Vue组件中使用Tinymce编辑器时,您可以直接导入Tinymce组件并在template中使用它。您可以根据需要通过props传递参数给Tinymce组件。 6. 最后,在整体的目录结构中,您需要确保Tinymce相关的文件和依赖正确地放置在对应的位置。 在使用Vue2 Tinymce富文本编辑器的过程中,您可能会遇到一些问题,比如路径找不到导致无法引入“tinymce/icons/default”的问题。这时,您可以尝试升级tinymce的版本来解决这个问题。 希望以上信息对您有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【vuevue2 中使用 Tinymce 富文本编辑器](https://blog.csdn.net/qq_46123200/article/details/130099360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值