wangEditor 上传附件

wangEditor 上传附件

img

创建 wangEditor

创建一个index.js文件

import React, { Component } from 'react'
import Wangeditor from 'wangeditor'
export default class RcWangEdite extends Component {
  constructor(props) {
    super(props)
    this.containerRef = React.createRef()
  }

  componentDidMount = () => {
    const div = this.containerRef.current;
    const editor = new Wangeditor(div);
    this.editor = editor;
    this.setCustomConfig();
    editor.create();
  };
  onChange = html => {
    this.props.onChange(html);
  };

  setCustomConfig = () => {
    const { customConfig } = this.props;
    this.editor.customConfig = {
      // 关闭粘贴内容中的样式
      pasteFilterStyle: false,
      // 忽略粘贴内容中的图片
      pasteIgnoreImg: true,
      // 使用 base64 保存图片
      uploadImgShowBase64: true
      ...customConfig,
    };
  };
  render() {
    return <div  ref={this.containerRef} />>;
  }
}

添加上传图片

修改setCustomConfig这个方法

setCustomConfig = () => {
  const { customConfig } = this.props
  this.editor.customConfig = {
    // 关闭粘贴内容中的样式
    pasteFilterStyle: false,
    // 忽略粘贴内容中的图片
    pasteIgnoreImg: true,
    // 上传图片到服务器
    uploadFileName: 'image', //设置文件上传的参数名称
    uploadImgServer: commonApi.imgUploadApi, //设置上传文件的服务器路径
    uploadImgMaxSize: 10 * 1024 * 1024, // 将图片大小限制为 10M
    uploadImgHooks: {
      before: function(xhr, editor, files) {
        before && before(xhr, editor, files)
      },
      fail: function(xhr, editor, result) {
        fail && fail(xhr, editor, result)
      },
      error: function(xhr, editor) {
        error && error(xhr, editor)
      },
      timeout: function(xhr, editor) {
        timeout && timeout(xhr, editor)
      },
      customInsert: (insertImg, result) => {
        const { code, data, msg } = result
        if (code == 0) {
          insertImg('/CMMS' + data.image_url)
        } else {
          message.error(msg)
        }
      },
    },
    ...customConfig,
  }
}

上传附件

首先我们写一个fileMenu.js的文件

/**
  editor: wangEdit的实例
  editorSelector: wangEdit挂载点的节点
  options: 一些配置
*/
export default (editor, editorSelector, options) => {
  editor.fileMenu = {
    init: function(editor, editorSelector) {
      const div = document.createElement('div')
      div.className = 'w-e-menu'
      div.style.zIndex = 10001
      const rdn = new Date().getTime()
      div.onclick = function() {
        document.getElementById(`up-${rdn}`).click()
      }

      const input = document.createElement('input')
      input.type = 'file'
      input.name = 'file'
      input.id = `up-${rdn}`
      input.className = 'upload-file-input'

      div.innerHTML = `<span class="upload-file-span">上传附件</span>`
      div.appendChild(input)
      editorSelector.getElementsByClassName('w-e-toolbar')[0].append(div)
    },
  }

  // 创建完之后立即实例化
  editor.fileMenu.init(editor, editorSelector)
}

index.js中引入fileMenu.js

import fileMenu from './fileMenu';
...
...
// 修改componentDidMount
componentDidMount = () => {
    const div = this.containerRef.current;

    const editor = new Wangeditor(div);
    this.editor = editor;
    this.setCustomConfig();
    editor.create();
    // 要放在editor实例化之后创建上传菜单
    fileMenu(editor, this.containerRef.current);
  };

做完这一步之后,wangEditor 富文本的菜单栏上已经有上传附件的按钮,并且点击可以选择文件了

对选择的文件进行上传

写一个上传文件的 js,uploadFile.js

import { message } from 'antd'
function uploadFile(files, options) {
  if (!files || !files.length) {
    return
  }
  let uploadFileServer = commonApi.imgUploadApi //上传地址
  const maxSize = 100 * 1024 * 1024 //100M
  const maxSizeM = maxSize / 1000 / 1000
  const maxLength = 1
  const uploadFileName = 'file'
  const uploadFileParams = {}
  const uploadFileParamsWithUrl = {}
  const timeout = 5 * 60 * 1000 //5 min
  // ------------------------------ 验证文件信息 ------------------------------
  const resultFiles = []
  const errInfo = []
  for (let file of files) {
    const name = file.name
    const size = file.size
    // chrome 低版本 name === undefined
    if (!name || !size) {
      return
    }
    if (maxSize < size) {
      // 上传附件过大
      errInfo.push('\u3010' + name + '\u3011\u5927\u4E8E ' + maxSizeM + 'M')
      return
    }
    // 验证通过的加入结果列表
    resultFiles.push(file)
  }
  // 抛出验证信息
  if (errInfo.length) {
    this._alert('附件验证未通过: \n' + errInfo.join('\n'))
    return
  }
  if (resultFiles.length > maxLength) {
    this._alert('一次最多上传' + maxLength + '个文件')
    return
  }
  // ------------------------------ 自定义上传 ------------------------------
  // 添加附件数据
  const formdata = new FormData()
  for (let file of resultFiles) {
    const name = uploadFileName || file.name
    formdata.append(name, file)
  }
  // ------------------------------ 上传附件 ------------------------------
  if (uploadFileServer && typeof uploadFileServer === 'string') {
    for (key in uploadFileParams) {
      val = encodeURIComponent(uploadFileParams[val])
      formdata.append(key, val)
    }
    // 定义 xhr
    const xhr = new XMLHttpRequest()
    xhr.open('POST', uploadFileServer)
    // 设置超时
    xhr.timeout = timeout
    xhr.ontimeout = function() {
      if (options.timeout && typeof options.timeout === 'function') {
        options.timeout(xhr, editor)
      }
      message.error('上传附件超时')
    }
    // 监控 progress
    if (xhr.upload) {
      xhr.upload.onprogress = function(e) {
        let percent = void 0
        // 进度条
        if (e.lengthComputable) {
          percent = e.loaded / e.total
          if (options.onProgress && typeof options.onProgress === 'function') {
            options.onProgress(percent)
          }
        }
      }
    }
    // 返回数据
    xhr.onreadystatechange = function() {
      let result = void 0
      if (xhr.readyState === 4) {
        if (xhr.status < 200 || xhr.status >= 300) {
          // hook - error
          if (options.onFail && typeof options.onFail === 'function') {
            options.onFail(xhr, editor)
          }
          return
        }
        result = xhr.responseText
        if ((typeof result === 'undefined' ? 'undefined' : typeof result) !== 'object') {
          try {
            result = JSON.parse(result)
          } catch (ex) {
            // hook - fail
            if (options.onFail && typeof options.onFail === 'function') {
              options.onFail(xhr, editor, result)
            }
            return
          }
        }
        const data = result || []
        if (data.code == 0) {
          options.onOk && options.onOk(data.data)
        }
      }
    }
    // 自定义 headers
    for (let key in uploadFileHeaders) {
      xhr.setRequestHeader(key, uploadFileHeaders[key])
    }
    // 跨域传 cookie
    xhr.withCredentials = false
    // 发送请求
    xhr.send(formdata)
  }
}
export default uploadFile

粗略的封装了一个上传文件的方法,options 主要暴露有以下几个 api

namedes
timeout超时的回调
onProgress上传进度的回调
onFail上传失败的回调
onOk上传成功的回调

其他的需要扩展的,可以自行添加

fileMenu.js中引入uploadFile.js

import uploadFile from './uploadFile';
...
...
// 修改`init`方法, 给`input`加上`onChange`事件
editor.fileMenu = {
  init: function(editor, editorSelector) {
    ...
    ...
    input.onchange = e => {
      // 使用uploadFile上传文件
      uploadFile(e.target.files, {
        onOk: data => {
          console.log(data)
          // 可以使用editor.txt.html(data)进行更新
        },
        onFail: err => {
          console.log(err)
        },
        onProgress: percent => {
          console.log(percent)
        },
      });
    };
  },
  ...
  ...
};

就这样子,wangEditor 实现了上传富文本的功能,wangEditor 也封装好了

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值