Vue tinymce 富文本编辑器 (图片过大适配,复制黏贴自动上传图片,拖拽上传图片)

项目需求可发布文章 需求涉及到富文本编辑器 经过查阅我选择了较为简便 不需要后端支持可独立完成的tinymce框架 官方文档也是相当完整 虽然都是全英文 但是有强大的 谷歌~ 没问题的

编辑器,tinymce  不需要后端配合  只需要把最终编辑完的富文本传给后端就好 很简单

下载tinymce

npm install tinymce

安装tinymce-vue 

npm install @tinymce/tinymce-vue 

 下载完成后在node_modules 中找到 tinymce/skins目录 ,复制下来 放置static

下载中文语言包 

tinymce提供了很多的语言包,这里我们下载语言包全英文 不懂 自己谷歌打开 翻译一下 选择下载zh_CN

初始化

页面引入文件

import tinymce from "tinymce/tinymce";

import Editor from "@tinymce/tinymce-vue";

import "tinymce/themes/silver";

注意tinymce的路径  

注册使用

<editor :init="init" v-model="content" class="issue-editor"></editor>

components:{ editor: Editor} 

初始化配置项官方文档

有使用powerPaste 将文件powerPaste 复制下来 放置static 引入即可使用

accept: "image/jpeg, image/png", //设置图片上传规则

maxSize: "2097152", //设置图片大小

height:'500',//设置编辑框大小

content:'',//编辑的内容 可以设置监听查看编辑输入的值

init: {

content_style: `

          *                         { padding:0; margin:0; }

          html, body                { height:100%; }

          img                       { max-width:100%; display:block;height:auto; }

          a                         { text-decoration: none; }

          iframe                    { width: 100%; }

          p                         { line-height:1.6; margin: 0px; }

          table                     { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }

          .mce-object-iframe        { width:100%; box-sizing:border-box; margin:0; padding:0; }

          ul,ol                     { list-style-position:inside; }

        `,///设置富文本的样式初始化

        skin_url: "/static/skins/ui/oxide", // tinymce UI引入

        language_url: "/static/zh_CN.js", //转中文文件

        language: "zh_CN",

        browser_spellcheck: true, // 拼写检查

        branding: false, // 去水印

        elementpath: false, //禁用编辑器底部的状态栏

        statusbar: false, // 隐藏编辑器底部的状态栏

        paste_data_images: true, // 允许粘贴图像

        menubar: false, // 隐藏最上方menu}

        // plugins:

        //   "image wordcount ",

        // toolbar: {

        //   type: [String, Array],

        //   default:

        //     "undo redo |  formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat"

        // },

        plugins:

          "advlist link image code textcolor paste textcolor colorpicker",

// plugins 配置必须有paste 否则图片无法黏贴成功   或者 改paste 为powerpaste  可不用引入paste

// paste只能实现文字或者图片单独黏贴   

     // powerpaste  可以实现 文字和图片一起黏贴 (本地图片会变成base64直接呈现)需要powerPaste文件的可私聊我要

        toolbar_items_size: "small",

        block_formats:

          "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;",

        toolbar1:

          "table |insertfile undo redo | formatselect | link unlink | uploadimg image media | name", // 工具栏1

        toolbar2:

          " fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | outdent indent | removeformat ", // 工具栏2


//引入powerpaste 注册   改plugins配置中的 paste为powerpaste

        external_plugins: {

          powerpaste: "/static/skins/powerpaste/plugin.js"

        },

        powerpaste_allow_local_images: true, //powerpaste允许黏贴

        powerpaste_word_import: "clean", //powerpaste黏贴的样式获取方式


        // setup: editor => { //自定义添加按钮

        //   editor.ui.registry.addButton("name", {

        //     tooltip: "选择标签",

        //     text: "选择标签",

        //     onAction: res => {

        //       console.log(res);

        //       self.labelDialogShow=true;

        //     },

        //   });

        // },

//粘贴事件数据官方文档

//黏贴内容时触发 获取元素 可自定义添加内容

        paste_postprocess: function(pluginApi, data) {

          // console.log(data);

          // // Apply custom filtering by mutating data.node

          // const additionalNode = document.createElement("div");

          // console.log(additionalNode);

          // additionalNode.innerHTML =

          //   "<p>This will go before the pasted content.</p>";

          // data.node.insertBefore(additionalNode, data.node.firstElementChild);

        },

//只要涉及上传图片就会触发方法 toolbar1 :uploadimg image media 工具栏呈现调用图片按钮 plugins:"image wordcount " 最上方呈现图片调用按钮 menubar   本地图片黏贴也是触发这个方法

        images_upload_handler: (blobInfo, success, failure) => {

          // console.log(blobInfo, success, failure);

          if (blobInfo.blob().size > self.maxSize) {

            failure("文件体积过大");

          }

          if (self.accept.indexOf(blobInfo.blob().type) >= 0) {

//上传图片符合规则 调用图片上传 上传成功 回调传入success 自己的上传图片接口

            self.handleImgUpload(blobInfo, success, failure);

          } else {

            failure("图片格式错误");

          }

          // https://blog.taiorient.com/file/appletUpload

          // const img = "data:image/jpeg;base64," + blobInfo.base64();

          // success(img);

        }

      }

上传图片接口

//图片上传

    handleImgUpload(blobInfo, success, failure) {

      //继承编辑器方法 blobInfo, success, failure

      console.log(blobInfo.blob());

      let formdata = new FormData();

      formdata.set("upload_file", blobInfo.blob());

      axios

        .post("https://blogtiorent.com/file/apletUpload", formdata)

        .then(res => {

          console.log(res);

          // 上传成功 回调传给编辑器

          success(

            "http://taioientcde.os-cn-senzhen.aiuncscom/image/" +

              res.data.data

          );

        })

        .catch(res => {

          //失败通知

          failure("error");

        });

    },

扩展插件 

引入

import 'tinymce/plugins/image'// 插入上传图片插件

import 'tinymce/plugins/media'// 插入视频插件

import 'tinymce/plugins/table'// 插入表格插件

import 'tinymce/plugins/link' //超链接插件

import 'tinymce/plugins/code' //代码块插件

import 'tinymce/plugins/lists'// 列表插件

import 'tinymce/plugins/contextmenu'  //右键菜单插件

import 'tinymce/plugins/wordcount' // 字数统计插件

import 'tinymce/plugins/colorpicker' //选择颜色插件

import 'tinymce/plugins/textcolor'  //文本颜色插件

import 'tinymce/plugins/fullscreen' //全屏

import "tinymce/plugins/preview"; //预览插件

import "tinymce/plugins/code";//代码块插件

// import "tinymce/plugins/paste";//图片黏贴插件

关于发布的文章在手机上图片过大处理

//在提交数据的时候 对img便签进行筛选替换   

 save(status) {

      // 处理图片过大问题

      this.content = this.content.replace(

        /<img [^>]*src=['"]([^'"]+)[^>]*>/gi,

        (mactch, capture) => {

          if(mactch.indexOf('max-width:')!=-1){

          }else if(mactch.indexOf('style=')!=-1){

            mactch = mactch.replace('style="','<img style="max-width:100%;')

          }else{

             mactch = mactch.replace('<img','<img style="max-width:100%;" ')

          }

          let current = "";

          this.newImgUrl.forEach(item => {

            if (capture == item.oriUrl) {

              current = item.filePath;

            }

          });

          current = current ? current : capture;

          return mactch.replace(

            /src=[\'\"]?([^\'\"]*)[\'\"]?/i,

            "src=" + current

          );

        }

      );

//处理powerPaste  div  align="center" 无法达到文字居中效果

      this.content = this.content.replace(

        /align="center"/gi,

        (mactch, capture) => {

          return mactch.replace('align="center"', 'style="text-align:center"');

        }

      );

      //  // 匹配并替换 任意html元素中 url 路径

      // this.content = this.content.replace(

      //   /url\(['"](.+)['"]\)/gi,

      //   (mactch, capture) => {

      //     let current = "";

      //     this.newImgUrl.forEach(item => {

      //       if (capture == item.oriUrl) {

      //         current = item.filePath;

      //       }

      //     });

      //     current = current ? current : capture;

      //     return mactch.replace(

      //       /url\((['"])(.+)(['"])\)/i,

      //       `url($1${current}$3) `

      //     );

      //   }

      // );

}

整理说明 图片黏贴上传 

图片黏贴上传 tinymce 的 paste插件 就可以支持了  有个小问题就是本地图片黏贴编辑器上传 不能与图文一起复制

  0. 引入插件  import "tinymce/plugins/paste"

  1. 基础设置  paste_data_images: true, // 允许粘贴图像

  2.工具栏配置 uploadimg image media

  3.通知使用插件 plugins: paste

  3.上传图片 触发方法 实现图片自定义上传   handleImgUpload(blobInfo, success, failure) { } 返回成功的success(url)

处理图文一起复制  也就是Word 复制上传 改paste 为powerpaste

  0.下载powerpaste文件放置自己项目 便于引用

  1.改plugins内配置paste为 powerpaste

  2.引用添加自定义插件 external_plugins:{powerpaste: "/static/skins/powerpastes/plugin.min.js" }, ( 注:引用文件版本要对 不然报错无法正常上传图片)

  3.基础配置  powerpaste_allow_local_images: true, //powerpaste允许黏贴  powerpaste_word_import: "clean", // 是否保留word粘贴样式  clean | merge    (具体可查看官方文档)

 到此完整解决 基本没有什么坑可以踩 很简单

看看效果​

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容