基于vue-html5-editor 封装的支持视频上传的富文本编辑器

483 阅读3分钟

主要是在modules模块添加自定义扩展

  • icons 补充 video: "fa el-icon-video-camera",
  • i18n zh-cn 补充 "video": '视频',
  • visibleModules 补充 video
  • modules 补充扩展方法
  • postUtilsUploadVideoCutApi这个方法需要支持上传视频 并且返回视频地址和视频封面地址,需要后端人员提供
import util from "@/util/api";
import {Message ,Loading } from 'element-ui';
export default {
    // 全局组件名称,使用new VueHtml5Editor(options)时该选项无效
    // global component name
    name: "vue-html5-editor",
    // 是否显示模块名称,开启的话会在工具栏的图标后台直接显示名称
    // if set true,will append module name to toolbar after icon
    showModuleName: true,
    // 自定义各个图标的class,默认使用的是font-awesome提供的图标
    // custom icon class of built-in modules,default using font-awesome
    icons: {
        text: "fa fa-pencil",
        color: "fa fa-paint-brush",
        font: "fa fa-font",
        align: "fa fa-align-justify",
        list: "fa fa-list",
        link: "fa fa-chain",
        unlink: "fa fa-chain-broken",
        tabulation: "fa fa-table",
        image: "fa fa-file-image-o",
        hr: "fa fa-minus",
        eraser: "fa fa-eraser",
        undo: "fa-undo fa",
        "full-screen": "fa fa-arrows-alt",
        info: "fa fa-info",
        video: "fa el-icon-video-camera",
        close: "fa fa-close",
    },
    // 配置图片模块
    // config image module
    image: {
        // 文件最大体积,单位字节  max file size
        sizeLimit: 1024 * 1024 * 100,
        // 上传参数,默认把图片转为base64而不上传
        // upload config,default null and convert image to base64
        upload: {
            url: '/api/media/file',
            headers: {},
            params: {},
            fieldName: 'file'
        },
        // 压缩参数,默认使用localResizeIMG进行压缩,设置为null禁止压缩
        // compression config,default resize image by localResizeIMG (https://github.com/think2011/localResizeIMG)
        // set null to disable compression
        compress: null, // 禁止压缩
      //   compress: {
      //       width: 1600,
      //       height: 1600,
      //       quality: 80
      //   },
        // 响应数据处理,最终返回图片链接
        // handle response data,return image url
        uploadHandler(responseText){
          console.log(responseText)
          let json = JSON.parse(responseText)
            if (json.code!=200) {
                alert(json.message)
            } else {
                return json.data
            }
        }
    },
    // 语言,内建的有英文(en-us)和中文(zh-cn)
    //default en-us, en-us and zh-cn are built-in
    language: "zh-cn",
    // 自定义语言
    i18n: {
        //specify your language here
        "zh-cn": {
            "align": "对齐方式",
            "image": "图片",
            "video": '视频',
            "list": "列表",
            "link": "链接",
            "unlink": "去除链接",
            "table": "表格",
            "font": "文字",
            "full screen": "全屏",
            "text": "排版",
            "eraser": "格式清除",
            "info": "关于",
            "color": "颜色",
            "please enter a url": "请输入地址",
            "create link": "创建链接",
            "bold": "加粗",
            "italic": "倾斜",
            "underline": "下划线",
            "strike through": "删除线",
            "subscript": "上标",
            "superscript": "下标",
            "heading": "标题",
            "font name": "字体",
            "font size": "文字大小",
            "left justify": "左对齐",
            "center justify": "居中",
            "right justify": "右对齐",
            "ordered list": "有序列表",
            "unordered list": "无序列表",
            "fore color": "前景色",
            "background color": "背景色",
            "row count": "行数",
            "column count": "列数",
            "save": "确定",
            "upload": "上传",
            "progress": "进度",
            "unknown": "未知",
            "please wait": "请稍等",
            "error": "错误",
            "abort": "中断",
            "reset": "重置",
            "close": "强制清除格式",
        }
    },
    // 隐藏不想要显示出来的模块
    // the modules you don't want
    hiddenModules: [],
    // 自定义要显示的模块,并控制顺序
    // keep only the modules you want and customize the order.
    // can be used with hiddenModules together
    visibleModules: [
        "text",
        "color",
        "font",
        "align",
        "list",
        "link",
        "unlink",
        "tabulation",
        "image",
        "video",
        "hr",
        "eraser",
        "close",
        "undo",
        "full-screen",
        "info",
    ],
    // 扩展模块,具体可以参考examples或查看源码
    // extended modules
    modules: [
    // 强制清除格式(原格式清除无法清除行内间距)
        {
          name: "close",
          icon: "fa fa-close",
          i18n: "close",
          init: function(editor) {
            console.log('init', editor)
          },
          handler: function (editor) {
            let str = editor.$refs.content.innerHTML
            let str1 = str.replace(/\s+style="[^"]*"/g, '') //去除style样式
            str1 = str1.replace(/\s+color="[^"]*"/g, '') //去除style样式
            str1 = str1.replace(/<\/?font[^>]*>/gi,"")
            editor.$refs.content.innerHTML = str1
          },
          destroyed: function (editor) {
            alert("destroyed", editor)
          }
        },
        {
          name: 'video',
          icon: 'el-icon-video-camera',
          i18n: 'video',
          show: true,
          init: function(editor) {
            console.log('emoji module init', editor)
          },
          //vue component
          dashboard: {
            // template: `<el-upload style="border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;"  action="" accept="video/*" :http-request="uploadVideo"> <i class="el-icon-plus avatar-uploader-icon" style="font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;"></i> </el-upload>`,
            template: `<el-upload ref="upload"
            class="upload"
            action="#"
            accept="video/*"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="uploadVideo"> 
              <el-button slot="trigger" size="mini" type="success">选择视频</el-button>
            </el-upload>`,
            data: function() {
              return {
                videoUrl: ''
              }
            },
            methods: {
              uploadVideo(file) {
                console.log(file)
                // 待添加
                let formData = new FormData();
                formData.append("file", file.raw);
                const loading = Loading.service({
                  lock: true,
                  text: "Loading",
                  spinner: "el-icon-loading",
                  background: "rgba(0, 0, 0, 0.7)",
                });
                util.postUtilsUploadVideoCutApi(formData).then((res) => {
                  loading.close();
                  console.log(res.data)
                  if (Number(res.data.code) == 200) {
                    let htmlval = `<p>&nbsp;&nbsp;&nbsp;</p>
                    <video controls="controls" style="max-width: 100%;" poster="${res.data.data.coverPicUrl}">
                    <source src="${res.data.data.fileUrl}">
                    </video>
                    <p>&nbsp;&nbsp;&nbsp;</p>`
                    this.$parent.execCommand('insertHTML', htmlval)
                  } else {
                    Message({
                      type: "warning",
                      message: "上传失败",
                    });
                  }
                }).catch((err) => {
                  loading.close();
                  Message({
                    message: err || "服务异常",
                    type: "error"
                    })
                })
              }
            }
          }
        }
    ]
  }