vue2+@tinymce/tinymce-vue富文本编辑器的实现

1.使用的第三方的库
npm install @tinymce/tinymce-vue@3.2.8 tinymce@5.10.9 --save
2.引入应用,直接上代码,支持上传图片,视频

<template>
  <div class="tinymce-container" ref="tinymceContainer">
    <Eidtor api-key="" v-if="initialized" v-model="tinymceHtml" :disabled="disabled" :width="width" @input="handleChange" id="tinymceId" :init="editorInit" ref="tinymce" />
    <input type="file" @change="handleVideoUpload" accept="video/*" style="visibility:hidden;width: 0px;height:0px;position: absolute;
  left: -9999px;" ref="videoFileInput">
  </div>
</template>
// 如果使用api-key 则这段可以不需要
import 'tinymce/tinymce';
import 'tinymce/themes/silver/theme';
import 'tinymce/icons/default/icons.min.js';
import 'tinymce/plugins/image/plugin.min.js';
import 'tinymce/plugins/link/plugin.min.js';
import 'tinymce/plugins/code/plugin.min.js';
import 'tinymce/plugins/table/plugin.min.js';
import 'tinymce/plugins/lists/plugin.min.js';
import 'tinymce/plugins/contextmenu/plugin.min.js';
import 'tinymce/plugins/wordcount/plugin.min.js';
import 'tinymce/plugins/colorpicker/plugin.min.js';
import 'tinymce/plugins/textcolor/plugin.min.js';
import 'tinymce/plugins/imagetools/plugin.min.js';
import 'tinymce/plugins/fullscreen/plugin.min.js';
import 'tinymce/plugins/paste/plugin.min.js';
import 'tinymce/plugins/media/plugin.min.js';
import '@/assets/static/tinymce/zh_CN.js';

import Eidtor from '@tinymce/tinymce-vue';

editorInit: {
        selector: this.tinymceId,  // 指定容器标识符
        language: 'zh_CN',
        plugins: 'link lists image code table colorpicker textcolor wordcount contextmenu paste media',
        toolbar: ' bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify  | outdent indent  | link unlink image  code customUploadButton | removeformat | undo redo ',  // 工具栏包含图片按钮
        font_family_formats: "Arial=arial,helvetica,sans-serif;宋体=SimSun;微软雅黑=Microsoft YaHei,SimHei;Impact=impact,chicago;", // 定义字体
        fontsize_formats: "10px 12px 14px 16px 18px 20px 24px 36px", // 定义字号
        height: 540,
        paste_data_images: true,
        content_style: '.mce-content-body { font-family: \'Arial\', sans-serif; font-size: 16px; } .mce-offscreen-selection{display: none;}',
        menubar: 'edit format table', // file edit insert view format table tools help
        images_upload_handler: (blobInfo, success, failure) => {
          this.upload(blobInfo, e => {
            success(e);
          });
        },
        // 其他配置...
        setup: (editor) => {
          editor.ui.registry.addButton('customUploadButton', {
           
            text: '上传视频',
            tooltip: '上传视频',
            onAction: () => {
              // 处理自定义上传视频按钮点击事件
              this.toggleVideoUpload();
            },
          });
        }
      }


 methods: {
    handleChange (content) {
      this.$emit('input', content);
    },
    upload: function (blobInfo, fn) {
      const isAccord =
        blobInfo.blob().type === 'image/jpeg' ||
        blobInfo.blob().type === 'image/png' ||
        blobInfo.blob().type === 'image/GIF' ||
        blobInfo.blob().type === 'image/jpg' ||
        blobInfo.blob().type === 'image/BMP';
      if (blobInfo.blob().type == isAccord) {
        this.$message.error('图片格式错误');
        fn && fn('');
        return;
      }
      let formData = new FormData();
      formData.append('file', blobInfo.blob());
      //这里为自己的上传接口调用方法
      uploadFile(formData)
        .then(res => {
          console.log('res', res)
          if (res.returnCode === "200") {
            fn && fn(res.url);
          } else {
            this.$message.error('图片上传失败');
            fn && fn('');
            setTimeout(() => {
              this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src="data.*?><\/p>/g, '');
              this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src="blob:*?><\/p>/g, '');
              this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src=""><\/p>/g, '');
            }, 10);
          }
        })
        .catch(error => {
          this.$message.error('图片上传失败');
          fn && fn('');
          setTimeout(() => {
            this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src="data.*?><\/p>/g, '');
            this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src="blob:*?><\/p>/g, '');
            this.tinymceHtml = this.tinymceHtml.replace(/<p><img\s?src=""><\/p>/g, '');
          }, 10);
          console.log(error);
        });
    },
    toggleVideoUpload (e) {
      this.$refs.videoFileInput.click();
    },
    handleVideoUpload (e) {
      const file = e.target.files[0];
      if (file) {
        const formData = new FormData();
        formData.append('file', file);

        uploadFile(formData)
          .then(response => {
            // 插入视频到编辑器
             this.insertVideo(response.data.url);
            this.$refs.videoFileInput.value = ''; // 重置文件输入框的值
          })
          .catch(error => {
            console.error('视频上传失败:', error);
          });
      }

    },
    insertVideo (url) {
      // 使用 TinyMCE 的 API 插入视频
      this.$refs.tinymce.editor.insertContent(`<p class="video-container" style="text-align: center;"><video  height="auto" src="${url}" controls></video></p>`);
    }
  }

3.内容的原样式回显,直接上代码,可以防止项目其他的样式影响

<iframe width="100%" frameborder="0" marginheight="0" marginwidth="0" :srcdoc="htmlStr" ref="contentIframe" id="contentIframe" class="content-iframe" sandbox="allow-same-origin allow-scripts"></iframe>
 methods: {
    sanitizeContent () {
      let htmlStr = `` // 这里换成富文本的字串内容
      let iframeDoc = `<html><head>
        <style>
          /* 在此处添加你的样式,或者通过 <link> 标签引入外部 CSS 文件 */
          .mce-content-body {
            font-family: 'Arial', sans-serif; /* 这里设置默认字体 */
            font-size: 16px; /* 这里设置默认字号 */
          }
        </style>
      </head><body>
        <div class="mce-content-body">${htmlStr)}</div>
      </body></html>`;
      this.htmlStr = iframeDoc
      this.$nextTick(() => {
        this.setIframeHeight();
      });

    },
    setIframeHeight () {
      const iframe = this.$refs.contentIframe;
      if (iframe) {
        iframe.onload = () => {
          const contentDocument = iframe.contentDocument || iframe.contentWindow.document;
          const contentHeight = contentDocument.body.offsetHeight + 100;
          iframe.style.height = contentHeight + 'px'
        };
      }
    }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值