富文本编辑器

@aligov/components-richtext-editor

富文本编辑器

基于https://github.com/margox/braft-editor 简单封装, braft 又是基于 draft

EditorState

draftjs 的原生 EditorState 对象 https://draftjs.org/docs/api-reference-editor-state.html

HTML/JSON 与 EditorState 互转

HTML/JSON 与 EditorState 互转为耗时操作, 尽量在有需要的时候在操作,以避免性能问题。

HTML/JSON -> EditorState

import Editor, { createEditorState } from "@aligov/components-richtext-editor";
const htmlString = "<p>Hellp World</p>";
const defaultValue = createEditorState(htmlString);
const App1 = <Editor defaultValue={defaultValue} />;

const rawString = `{"blocks":[{"key":"cl5he","text":"Hello World","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":6,"length":5,"style":"ITALIC"}],"entityRanges":[],"data":{"nodeAttributes":{}}}],"entityMap":{}}`;
const defaultValue = createEditorState(rawString);
const App2 = <Editor defaultValue={defaultValue} />;

EditorState -> HTML

const onChange = editorState => console.log(editorState.toHTML());
const App = <Editor defaultValue={defaultValue} onChange={onChange} />;

EditorState -> JSON

const onChange = editorState => {
  const rawObject = editorState.toRAW(true);
  const jsonString = JSON.stringify(rawObject);
  console.log(jsonString);
};
const App = <Editor defaultValue={defaultValue} onChange={onChange} />;

注意事项

性能

https://www.yuque.com/braft-editor/be/lzwpnr#1bbbb204

美化输出 HTML

https://www.yuque.com/braft-editor/be/lzwpnr#b79b9e83

持久化存储

html 字符串也可以用于持久化存储,但是对于比较复杂的富文本内容,在反复编辑的过程中,可能会存在格式丢失的情况,比较标准的做法是在数据库中同时存储 raw 字符串和 html 字符串,分别用于再次编辑和前台展示。

API

参数名 说明 必填 类型 默认值 备注
value EditorState 对象 受控模式使用
defaultValue 默认值 EditorState 对象 非控模式使用
onChange 状态变化函数 Function(value: EditorState ) : void 默认会开启 debounce
controls 需要展示的控件 Array 见源码 一般不填,使默认值 样例见: 见 https://www.yuque.com/braft-editor/be/gz44tn#bo49ph
contentStyle 编辑区域的样式 , Object 见源码 样例见: https://braft.margox.cn/demos/custom

DEMO 列表

基础用法

基础用法。

import React, { Component } from "react";
import { Button } from '@alifd/next';
import ReactDOM from "react-dom";
import RichtextEditor, { createEditorState } from "@aligov/components-richtext-editor";

const htmlString = "<p>富文本<b>编辑</b>器</p>";
const rawString = `{"blocks":[{"key":"2laso","text":"富文本编辑器","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":3,"length":2,"style":"BOLD"}],"entityRanges":[],"data":{"nodeAttributes":{}}}],"entityMap":{}}`;


class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      editorState: createEditorState(rawString),
      // HTML也可以 但不推荐
      // editorState: createEditorState(htmlString),
    }
  }
  onChange(editorState) {
    this.setState({
      editorState
    })
  }

  onSave = () => {
    const {editorState} = this.state;
    const data = {
      raw: JSON.stringify(editorState.toRAW(true)),
      html: editorState.toHTML(),
    };
    console.log(data);
  }
  render() {
    return (
      <div>
        <p style={{color: 'red', fontSize: '30px'}}>HTML/JSON 与 EditorState 互转为耗时操作, 尽量在有需要的时候在操作,以避免性能问题。本样例只是演示其用法</p>
        
        <RichtextEditor 
          value={this.state.editorState}
          onChange={(editorState) => this.onChange(editorState)}
          contentStyle={{height: 200}}/>
        
        <p style={{color: 'red'}}>
          <Button type="primary" onClick={this.onSave}>数持久化</Button>
          <br />
          html字符串也可以用于持久化存储,但是对于比较复杂的富文本内容,在反复编辑的过程中,可能会存在格式丢失的情况,比较标准的做法是在数据库中同时存储raw字符串和html字符串,分别用于再次编辑和前台展示。</p>
        
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);