Skip to content
kailunyao edited this page Jan 8, 2019 · 6 revisions

react-ueditor 使用文档

基本使用

引入 ueditor 文件夹

拷贝该项目 vendor 目录下的 ueditor 到你的项目下,或上传到你自己的服务器、CDN

使用组件

import ReactUeditor from 'ifanrx-react-ueditor'

<ReactUeditor
  ueditorPath={`${window.YOUR_PATH}/ueditor`}"
/>

支持的属性

Property Description Type Must
config 在实例化时传入配置参数 obj no
extendControls 扩展工具栏(目前仅支持弹出模态框方式) array no
getRef 获取 ueditor 实例 func no
handlePasteImage 用于处理复制进来的图片 func no
multipleImagesUpload 支持多文件上传,默认为 false bool no
onChange 编辑器内容改变事件 func no
onReady ueditor 加载完成事件 func no
plugins 需要使用的插件 array no
progress 上传进度 num no
ueditorPath ueditor 文件夹路径(建议使用绝对路径,或上传到 CDN) string yes
uploadAudio 音频上传回调 func no
uploadImage 图片上传回调 func no
uploadVideo 视频上传回调 func no
value 初始化值 string no

plugins 现支持:

  • 图片上传 uploadImage
  • 视频上传 uploadVideo
  • 音频上传 uploadAudio
  • 插入代码 insertCode
  • 插入链接 insertLink

使用实例

实时获取编辑器最新内容

class SimpleExample extends React.Component {
  updateEditorContent = content => {
    this.content = content
  }

  render() {
    return (
      <ReactUeditor
        ueditorPath='../vendor/ueditor'
        onChange={this.updateEditorContent}
      />
    )
  }
}

设置异步数据

class AsyncExample extends React.Component {
  constructor() {
    super()
    this.editorResult = ''
    this.state = {
      content: '',
    }
    this.timer = null
  }

  componentDidMount() {
    this.timer = setTimeout(() => {
      this.setState({
        content: '我是异步加载回来的数据',
      })
    }, 2000)
  }

  componentWillUnmount() {
    clearTimeout(this.timer)
  }

  updateEditorContent = content => {
    this.editorResult = content
  }

  render() {
    let {content} = this.state
    return (
      <div>
        <ReactUeditor
          ueditorPath='../vendor/ueditor'
          value={content}
          onChange={this.updateEditorContent}
        />
      </div>
    )
  }
}
  • 由于 ueditor 是一个不受组件,因此,你不能在 onChange 中对其重新 setState

使用上传图片插件

class MediaExample extends React.Component {
  updateEditorContent = content => {
    this.editorResult = content
  }

  uploadImage = e => {
    return new Promise(function(resolve, reject) {
      resolve(window.URL.createObjectURL(e.target.files[0]))
    })
  }

  render() {
    return (
      <ReactUeditor
        ueditorPath='../vendor/ueditor'
        plugins={['uploadImage']}
        uploadImage={this.uploadImage}
        onChange={this.updateEditorContent}
        multipleImagesUpload={true}
      />
    )
  }
}

uploadImage 方法需要返回一个 promise,以便通知 react-ueditor 你已经上传成功了

使用上传视频插件

class MediaExample extends React.Component {
  constructor() {
    super()
    this.state = {
      progress: -1,
    }
  }

  updateEditorContent = content => {
    this.editorResult = content
  }

  uploadVideo = e => {
    let _this = this
    return new Promise(function(resolve, reject) {
      let i = 0
      let instance = setInterval(() => {
        if (i !== 100) {
          _this.setState({progress: ++i})
        }
      }, 50)
      setTimeout(() => {
        resolve('https://cloud-minapp-1131.cloud.ifanrusercontent.com/1eBb1SeNlayvGEKT.mp4')
        _this.setState({progress: -1})
        clearInterval(instance)
      }, 5100)
    })
  }

  render() {
    let {progress} = this.state

    return (
      <ReactUeditor
        ueditorPath='../vendor/ueditor'
        onChange={this.updateEditorContent}
        plugins={['uploadVideo']}
        uploadVideo={this.uploadVideo}
        progress={progress}
      />
    )
  }
}

同样 uploadVideo 也需要返回 promise,同时你可以在组件外面计算上传进度,将进度值传给 progress,便可在视频上传模态框中看到上传进度

直接获取 ueditor ref 已操作 ueditor

class EditorRefExample extends React.Component {
  constructor() {
    super()
    this.ueditorRef = null
    this.state = {
      content: '',
    }
  }

  getUeditor = ref => {
    this.ueditorRef = ref
  }

  getUeditorContent = ref => {
    this.setState({
      content: this.ueditorRef.getContent(),
    })
  }

  handleReady = () => {
    this.ueditorRef.setHeight(200)
  }

  render() {
    let {content} = this.state

    return (
      <div>
        <ReactUeditor
          ueditorPath='../vendor/ueditor'
          getRef={this.getUeditor}
          onChange={this.updateEditorContent}
          onReady={this.handleReady}
        />
        <button onClick={this.getUeditorContent}>获取内容</button>
        <p>{content}</p>
      </div>
    )
  }
}

ReactUeditor 会在加载后,调用 getUeditor,从而把 ueditor ref 设置到 this.ueditorRef,拿到它你就可以直接调用 ueditor 的 API 来操作,如获取编辑器内容,动态设置编辑器高度等等

扩展工具栏

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      inputValue: '',
    }
  }

  getUeditor = ref => {
    this.ueditorRef = ref
  }

  handleInputChange = e => {
    this.setState({
      inputValue: e.target.value,
    })
  }

  render() {
    return (
      <ReactUeditor
        debug
        ueditorPath='../vendor/ueditor'
        getRef={this.getUeditor}
        extendControls={[
          {
            name: 'test',
            menuText: 'test',
            title: '测试模态框',
            // 图标定义,遵循 ueditor 的格式
            cssRules: 'background: url(' + testIcon + ') !important; background-size: 20px 20px !important;',
            zIndex: 1,
            alignStyle: 'middle',
            component: <input onChange={this.handleInputChange} />,
            onConfirm: () => {
              this.ueditorRef.execCommand('inserthtml', this.state.inputValue, true)
            },
          },
        ]}
      />
    )
  }
}

目前 react-ueditor 允许以弹出模态框的方式添加扩展,你可以在模态框中直接使用已有的组件。配合 ueditor ref,你可以更灵活地操作 ueditor

对粘贴进来的图片进行处理

某些情况下,外部图片地址设置了访问权限,例如从微信公众号编辑器复制过来的图片,因此,有时候需要将图片重新上传都开发者自己的服务器,因此 react-ueditor 也暴露了相应的接口

class PasteImageExample extends React.Component {
  handlePasteImage = src => {
    return new Promise(function(resolve) {
      setTimeout(() => {
        resolve('https://s3.ifanr.com/wp-content/uploads/2019/01/WechatIMG974.jpeg!720')
      }, 1000)
    })
  }

  updateEditorContent = newContent => {
    console.log('newContent', newContent)
  }

  render() {
    return (
      <ReactUeditor
        ueditorPath='../vendor/ueditor'
        handlePasteImage={this.handlePasteImage}
        onChange={this.updateEditorContent}
      />
    )
  }
}