自定义Block渲染

这篇文章讨论怎么定制Draft的block渲染。Block渲染用于定义支持的block类型和它们的渲染器,以及将解析之后的的内容转换为已知的Draft block类型。

当解析内容或者使用convertFromHTML时,Draft会将标签和Draft block进行匹配,将解析后的内容转化为已知的block渲染类型。

默认的block渲染表

HTML标签 Draft block类型
\

header-one
\

header-two
\

header-three
\

header-four
\
header-five
\
header-six
\
blockquote
\
code-block
\
atomic
\
  • unordered-list-item,ordered-list-item **
    \
    unstyled *

    ** - 这个Block类型建立在父级元素为\

      和\
        的基础上

    * - 任何不在上边列表的block类型都会被当做unstyled

    配置block渲染列表

    Draft默认的block渲染可以通过给Editor组件传入类型为Immutable MapblockRender prop来重写。

    例如改写默认的block渲染。

    // 下边的例子中,只允许「heading-two」作为唯一有效的block类型
    // 并且将unstyled元素也更新为「h2」
    const blockRenderMap = Immutable.Map({
      'header-two': {
        element: 'h2'
      },
      'unstyled': {
        element: 'h2'
      }
    });
    
    class RichEditor extends React.Component {
      render() {
        return (
          <Editor
            ...
            blockRenderMap={blockRenderMap}
          />
        );
      }
    }
    

    除了重写block类型,我们还能够添加自定义的block类型。通过DefaultDraftBlockRenderMap来新建一个blockRenderMap。

    扩展默认的block render map。

    const blockRenderMap = Immutable.Map({
      'section': {
        element: 'section'
      }
    });
    
    // 将'section' 作为可用的block类型,并更新unstyled元素
    // 同时保持其它的block类型
    const extendedBlockRenderMap = Draft.DefaultDraftBlockRenderMap.merge(blockRenderMap);
    
    class RichEditor extends React.Component {
      render() {
        return (
          <Editor
            ...
            blockRenderMap={extendedBlockRenderMap}
          />
        );
      }
    }
    

    当Draft解析一个已经被解析的html,它将html元素转化为Draft block类型。如果你想让其它的标签也能转化为指定的block类型,你可以在block config中添加aliasedElements

    unstyled block类型别名的使用:

    'unstyled': {
      element: 'div',
      aliasedElements: ['p'],
    }
    

    自定义 block wrappers

    默认的情况下,html标签被用来包裹block类型。通过blockRenderMap,React组件也能够用来包裹EditorBlock。

    在解析或者使用convertFromHTML时html会被扫描,来匹配特定的标签。一个wrapper会用来承载特定的block类型。例如:

    Draft 使用\

      或 \
        作为\
      • 的wrapper。wrapper可以在其它类型的block上使用。

    在自定义block类型上使用React组件作为wrapper的例子:

    class MyCustomBlock extends React.Component {
      constructor(props) {
        super(props);
      }
    
      render() {
        return (
          <div className='MyCustomBlock'>
            {/* 这里this.props.children 包含<section>,因为section匹配上了这个组件 */}
            {this.props.children}
          </div>
        );
      }
    }
    
    const blockRenderMap = Immutable.Map({
      'MyCustomBlock': {
        // 在解析过程中使用的html标签,用来对应我们的组件;
        // 它也会被保留,不会被替换。
        element: 'section',
        wrapper: MyCustomBlock,
      }
    });
    
    // 在支持原有block类型的基础上添加我们的myCustomBlock类型
    const extendedBlockRenderMap = Draft.DefaultDraftBlockRenderMap.merge(blockRenderMap);
    
    class RichEditor extends React.Component {
      ...
      render() {
        return (
          <Editor
            ...
            blockRenderMap={extendedBlockRenderMap}
          />
        );
      }
    }
    

    results matching ""

      No results matching ""