vue 后台管理系统富文本组件(四)UEditor(集成 135 编辑器插件)

标签: vue  那些年写过的企业级中后台vue  react组件  vue  html  ueditor  135编辑器

vue 后台管理系统富文本组件(四)UEditor(集成 135 编辑器插件)

简介

135 编辑器应用于微信文章、企业网站、以及论坛等多种平台,支持秒刷、一键排版、全文配色、公众号管理、微信变量回复、48 小时群发、定时群发、云端草稿、文本校对等 40 多项功能与服务, 像拼积木一样组合排版的文章。 135 编辑器因其简单的操作,强大的功能和美观的排版深受广大用户喜爱。135 编辑器本质是基于百度 UEditor 二次开发的,因公司业务需求开发了本文组件。

本文章源码-GitHub仓库地址

准备工作

  1. 下载 UEditor

    UEditor 官网下载链接 如图下载开发版 1.4.3.3 完整源码-点击下载
    在这里插入图片描述

    下载完成后的目录如下
    在这里插入图片描述
    其中好多文件目录我们并不需要,如下只保留这些文件。editor_api.js文件来自 _examples文件夹,_examples文件夹删除前把这个文件提取出来。
    在这里插入图片描述

  2. 基于vue-cli 3 搭建项目,主要依赖说明 (先安装,scss和element-ui先配置,步骤略)

    {
      "axios": "^0.19.0",
      "core-js": "^3.4.4",
      "element-ui": "^2.13.0",
      "vue": "^2.6.10",
      "vue-router": "^3.1.3",
      "vuex": "^3.1.2"
    }
    
  3. vue.config.js 配置如下,( assetsDirstaticpublicPath"./"

    module.exports = {
      publicPath: "./",
      outputDir: "dist",
      assetsDir: "static",
      productionSourceMap: false,
      lintOnSave: true,
      devServer: {
        port: 8080,
        open: true,
        overlay: {
          warnings: true,
          errors: true
        }
      }
    };
    
  4. 然后在public 里新建文件夹static 把下载的ueditor文件夹整个拿过来,放到static目录下

    在这里插入图片描述

  5. 修改editor_api.js文件里的 baseURL变量

    baseURL = '../_src/' 改为 baseURL = 'static/ueditor/_src/'

  6. 添加 135 插件,添加 135 插件文档

    a. 下载
    http://www.135editor.com/js/ueditor/plugins/135editor.js

    http://www.135editor.com/js/ueditor/dialogs/135editor/135EditorDialogPage.html

    b.放置文件
    135editor.js文件放到 public/static/ueditor/_src/plugins 文件夹下

    135EditorDialogPage.html文件放到public/static/ueditor/dialogs/135editor 文件夹下 没有135editor文件夹需要新建)

    c. 修改配置文件
    在 ueditor.config.js 中 toolbars 项里增加一个 135editor 菜单项

      toolbars: [ ['135editor', 'fullscreen', 'source', '|',  'undo', redo', .... ]]
    

    d.添加 css (在后文 src/components/UEditor/index.vue 文件里添加)

    .edui-button.edui-for-135editor
      .edui-button-wrap
      .edui-button-body
      .edui-icon {
      background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important;
      background-size: 85%;
      background-position: center;
      background-repeat: no-repeat;
    }
    
  7. public/index.html 里添加文件 ueditor.config.js,editor_api.js,zh-cn.js

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />
        <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
        <title>135</title>
      </head>
      <body>
        <noscript>
          <strong
            >We're sorry but 135 doesn't work properly without JavaScript
            enabled. Please enable it to continue.</strong
          >
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
    
        <!-- ueditor -->
        <script
          type="text/javascript"
          src="static/ueditor/ueditor.config.js"
        ></script>
        <script
          type="text/javascript"
          src="static/ueditor/editor_api.js"
        ></script>
        <script
          type="text/javascript"
          src="static/ueditor/lang/zh-cn/zh-cn.js"
        ></script>
      </body>
    </html>
    

组件

  1. 文件目录
    在这里插入图片描述

  2. 核心代码
    src/components/UEditor/index.vue

    <template>
      <div class="custom-ueditor-container">
        <div
          :id="id"
          :style="{ width: width + 'px', height: height + 'px' }"
        ></div>
        <multiple-upload
          class="custom-upload-button"
          :button-style="buttonStyle"
          @success="imageSuccess"
        />
      </div>
    </template>
    <script>
      /* eslint-disable eqeqeq */
      /* eslint-disable no-undef */
      /* eslint-disable no-unused-vars */
      /* eslint-disable space-in-parens */
      import axios from "axios";
      import config from "./config"; // 配置文件见下文
      import MultipleUpload from "../MultipleUpload";  // MultipleUpload组件参考 https://blog.csdn.net/qq_39953537/article/details/100039094
      import { uploadHtml } from "@/api/upload"; // 接口根据自己后端提供的写
    
      const UE = window.UE;
    
      // 设置 UEDITOR_HOME_URL
      window.UEDITOR_HOME_URL = "static/ueditor";
      export default {
        components: {
          MultipleUpload
        },
        props: {
          width: {
            type: Number,
            default: 750
          },
          height: {
            type: Number,
            default: 400
          },
          html: {
            type: String,
            default: ""
          }
        },
        data() {
          return {
            ueditor: null,
            buttonStyle: {
              padding: "3px 6px"
            }
          };
        },
        computed: {
          // 生成唯一id
          id() {
            const id =
              Math.random()
                .toString(36)
                .substring(2, 15) +
              "-ueditor-" +
              +new Date();
            return id;
          }
        },
        watch: {
          html(val) {
            this.loadUrl(val);
          }
        },
        mounted() {
          this.init();
        },
        beforeDestroy() {
          this.destroyEditor();
        },
    
        methods: {
          // 编辑器初始化
          init() {
            this.ueditor = UE.getEditor(this.id, { ...config });
            if (this.html) {
              this.loadUrl(this.html);
            }
          },
    
          // 加载html内容
          async loadUrl(url) {
            try {
              const { data } = await axios.get(url);
              this.setContent(data);
            } catch (error) {
              this.setContent("服务器数据加载失败,请重试!");
            }
          },
    
          // 图片上传成功添加到编辑器
          async imageSuccess(urlList) {
            try {
              let imageTemplateList = "";
              urlList.forEach(item => {
                const image = `<img style="max-width:100%;" src="${item}">`;
                imageTemplateList = imageTemplateList + image;
              });
              this.inserthtml(imageTemplateList, true);
              this.$message.success("上传成功!");
            } catch (error) {
              console.log(error);
              this.$message.error(error);
            }
          },
    
          // 编辑器内容上传到cos,调用返回url
          async content2Url() {
            try {
              if (!this.hasContent()) {
                throw new Error("未输入内容");
              }
              const content = this.getContent();
              const res = await uploadHtml(content);
              return res;
            } catch (error) {
              throw new Error(error);
            }
          },
    
          // 设置编辑器内容  isAppendTo为true时是追加内容到编辑器,false是覆盖
          setContent(content, isAppendTo) {
            if (!content) return;
            this.ueditor.ready(() => {
              this.ueditor.setContent(content, isAppendTo);
            });
          },
    
          // 在当前光标位置插入html内容
          inserthtml(content) {
            if (!content) return;
            this.ueditor.execCommand("inserthtml", content);
          },
    
          // 获取编辑器内容
          getContent() {
            return this.ueditor.getContent();
          },
    
          // 设置编辑器聚焦
          setFocus() {
            this.ueditor.focus();
          },
    
          // 判断编辑器是否有内容
          hasContent() {
            return this.ueditor.hasContents();
          },
    
          // 销毁编辑器
          destroyEditor() {
            this.ueditor.destroy();
          }
        }
      };
    </script>
    <style lang="scss" scoped>
      .custom-ueditor-container {
        position: relative;
        color: #373737;
        line-height: 22px;
        .custom-upload-button {
          position: absolute;
          left: 650px;
          top: 32px;
          z-index: 99;
        }
      }
    </style>
    
    <style>
    /* 添加135编辑器插件样式 */
      .edui-button.edui-for-135editor
        .edui-button-wrap
        .edui-button-body
        .edui-icon {
        background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important;
        background-size: 85%;
        background-position: center;
        background-repeat: no-repeat;
      }
    </style>
    

    src/components/UEditor/config/index.js

    import toolbars from "./toolbars";
    const config = {
      toolbars,
      zIndex: 99, // 编辑器层级的基数,默认是900
      wordCount: false, // 是否开启字数统计
      wordCountMsg: "", // 输入提示
      maximumWords: Number.MAX_VALUE, // 允许的最大字符数
      serverUrl: "", // 服务器统一请求接口路径
      enableAutoSave: false, // 不自动保存
      enableContextMenu: false, // 禁用右键
      autoHeightEnabled: false, // 不自动扩展编辑器高度
      elementPathEnabled: false // 不显示html元素路径
    };
    
    export default config;
    

    src/components/UEditor/config/toolbars.js

    const toolbars = [
      [
        // 'fullscreen', // 全屏
        // 'source',  // 源代码
        // '|',
        // 'undo',
        // 'redo',
        // '|',
        "bold",
        "italic",
        "underline",
        "fontborder",
        "strikethrough",
        "superscript",
        "subscript",
        "removeformat",
        "formatmatch",
        "autotypeset",
        "blockquote",
        "pasteplain",
        "|",
        "forecolor",
        "backcolor",
        // 'insertorderedlist',  // 有序
        // 'insertunorderedlist', // 无序
        "selectall",
        "cleardoc",
        "|",
        "rowspacingtop",
        "rowspacingbottom",
        "lineheight",
        "|",
        // 'customstyle',
        "paragraph",
        // 'fontfamily',
        "fontsize",
        "|",
        // 'directionalityltr',  // 文字方向
        // 'directionalityrtl', // 文字方向
        "indent",
        "|",
        "justifyleft",
        "justifycenter",
        "justifyright",
        "justifyjustify",
        "|",
        "touppercase",
        "tolowercase",
        // '|',
        // 'link',
        // 'unlink',
        // 'anchor',
        "|",
        "imagenone",
        "imageleft",
        "imageright",
        "imagecenter",
        "|",
        // 'simpleupload',
        // 'insertimage',
        "emotion",
        // 'scrawl', // 涂鸦
        // 'insertvideo',
        // 'music',
        // 'attachment', // 附件
        // 'map',
        // 'gmap',
        // 'insertframe',
        // 'insertcode',
        // 'webapp',
        // 'pagebreak', // 分页
        "template",
        // 'background', // 编辑器背景
        "|",
        "horizontal",
        "date",
        "time",
        "spechars",
        // 'snapscreen', // 截图
        // 'wordimage',
        // '|',
        // 'inserttable',
        // 'deletetable',
        // 'insertparagraphbeforetable',
        // 'insertrow',
        // 'deleterow',
        // 'insertcol',
        // 'deletecol',
        // 'mergecells',
        // 'mergeright',
        // 'mergedown',
        // 'splittocells',
        // 'splittorows',
        // 'splittocols',
        // 'charts',
        "|",
        // 'print',
        // 'preview',
        "searchreplace"
        // 'help',
        // 'drafts'
      ]
    ];
    
    export default toolbars;
    
  3. 使用

    <template>
     <div class="demo">
        <u-editor ref="editor" :height="500" :html="html" @input="getContent" />
        <div class="get-url-btn-warpper">
        <el-button type="primary" size="small" @click="getContentUrl">
            获取上传后的链接
        </el-button>
        </div>
     </div>
    </template>
    
    <script>
    import UEditor from '@/components/UEditor'
    export default {
        name: 'UEditorDemo',
        components: {
            UEditor
        },
        data() {
            return {
            html: '',
            content: ''
            }
        },
        methods: {
            // 获取商品详情编辑器内容
            getContent(content) {
            this.content = content
            },
            // 获取上传后的链接
            async getContentUrl() {
    	        try {
    	            const url = await this.$refs.editor.content2Url()
    	            console.log(url)
    	        } catch (error) {
    	            this.$message.warning(error.message)
    	        }
            }
        }
    }
    </script>
    
    <style lang="scss">
    .demo {
    margin: 50px;
    }
    .get-url-btn-warpper {
    margin-top: 10px;
    }
    </style>
    
  4. 使用效果
    在这里插入图片描述
    在这里插入图片描述

    参考链接

    1. http://www.135plat.com/135_ueditor_plugin.html
    2. http://fex.baidu.com/ueditor/
    3. http://ueditor.baidu.com/doc/
版权声明:本文为qq_39953537原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39953537/article/details/103891046