当前位置: 首页 > 工具软件 > Draft.js > 使用案例 >

Draft.js react 编辑器 HelloWorld

从建明
2023-12-01

安装
npm install –save draft-js

核心概念
Entity:抽象的元素
decorator:对文档的解释方法(核心开发内容)
decorator的strategy: 查找方法
decorator的component:绘制方法

参考文档 http://facebook.github.io/draft-js/docs/overview.html

import React from 'react';
var ReactDOM = require('react-dom');
import {

    convertFromRaw,
    convertToRaw,
    CompositeDecorator,
    ContentState,
    Editor,
    EditorState,
    Entity,
} from 'draft-js';


// 样式
const styles = {
    root: {
        fontFamily: '\'Helvetica\', sans-serif',
        padding: 20,
        width: 600,
    },
    editor: {
        border: '1px solid #ccc',
        cursor: 'text',
        minHeight: 80,
        padding: 10,
    },
    button: {
        marginTop: 10,
        textAlign: 'center',
    },
    immutable: {
        backgroundColor: 'rgba(0, 0, 0, 0.2)',
        padding: '2px 0',
    },
    mutable: {
        backgroundColor: 'rgba(204, 204, 255, 1.0)',
        padding: '2px 0',
    },
    segmented: {
        backgroundColor: 'rgba(248, 222, 126, 1.0)',
        padding: '2px 0',
    },
};

// 绘制方法
const TokenSpan = (props) => {

    // 获取样式
    const style = getDecoratedStyle(
        Entity.get(props.entityKey).getMutability()
    );
    return (
        <span {...props} style={style}>
            {props.children}
          </span>
    );
};

function getEntityStrategy(mutability) {
    return function (contentBlock, callback) {
        contentBlock.findEntityRanges(
            (character) => {
                const entityKey = character.getEntity();
                if (entityKey === null) {
                    return false;
                }
                return Entity.get(entityKey).getMutability() === mutability;
            },
            callback
        );
    };
}

// 获取样式
function getDecoratedStyle(mutability) {
    switch (mutability) {
        case 'IMMUTABLE':
            return styles.immutable;
        case 'MUTABLE':
            return styles.mutable;
        case 'SEGMENTED':
            return styles.segmented;
        default:
            return null;
    }
}

// 原始 初始化诗句
const rawContent = {
    blocks: [
        {
            text: (
                'This is an "immutable" entity: Superman. Deleting any ' +
                'characters will delete the entire entity. Adding characters ' +
                'will remove the entity from the range.'
            ),
            type: 'unstyled',
            // 范围
            entityRanges: [{offset: 31, length: 8, key: 'first'}],
        },
        {
            text: '',
            type: 'unstyled',
        },
        {
            text: (
                'This is a "mutable" entity: Batman. Characters may be added ' +
                'and removed.'
            ),
            type: 'unstyled',
            entityRanges: [{offset: 28, length: 6, key: 'second'}],
        },
        {
            text: '',
            type: 'unstyled',
        },
        {
            text: (
                'This is a "segmented" entity: Green Lantern. Deleting any ' +
                'characters will delete the current "segment" from the range. ' +
                'Adding characters will remove the entire entity from the range.'
            ),
            type: 'unstyled',
            entityRanges: [{offset: 30, length: 13, key: 'third'}],
        },
    ],

    entityMap: {
        first: {
            type: 'TOKEN',
            mutability: 'IMMUTABLE',
        },
        second: {
            type: 'TOKEN',
            mutability: 'MUTABLE',
        },
        third: {
            type: 'TOKEN',
            mutability: 'SEGMENTED',
        },
    },
};


class MyEditor extends React.Component {
    constructor(props) {
        super(props);

        this.focus = () => this.refs.editor.focus();

        // 解码器
        const decorator = new CompositeDecorator([
            {
                // 查找方法
                strategy: getEntityStrategy('IMMUTABLE'),
                // 元素
                component: TokenSpan,
            },
            {
                strategy: getEntityStrategy('MUTABLE'),
                component: TokenSpan,
            },
            {
                strategy: getEntityStrategy('SEGMENTED'),
                component: TokenSpan,
            },
        ]);

        // 初始化内容
        const blocks = convertFromRaw(rawContent);


        this.state = {
            editorState: EditorState.createWithContent(blocks, decorator),
        };


        this.onChange = (editorState) => this.setState({editorState});


    }


    render() {
        return <div style={styles.root}>
            <div onClick={this.focus}><Editor editorState={this.state.editorState} ref="editor"
                                              onChange={this.onChange}/></div>
        </div>;
    }
}
export default  MyEditor;
 类似资料: