React introduces the rich text editor TinyMCE

 

This week, I made a PC service background requirement, requiring a rich text editor, inserting pictures, tables, font size background color, etc.,

Finally introduced the rich text editor TinyMCE

 

For the introduction of TinyMCE:

TinyMCE is an easy-to-use and powerful WYSIWYG rich text editor. Similar programs include: UEditor, Kinditor, Simditor, CKEditor, wangEditor, Suneditor, froala, etc.

The advantages of TinyMCE:

  • Open source and commercially available, based on LGPL2.1
  • Rich plug-ins, the built-in plug-ins basically cover the functions required daily
  • Rich interfaces, strong scalability, and the ability to expand functions indefinitely
  • The interface looks good, in line with modern aesthetics
  • Provide three modes: classic, inline, and immersive without interference
  • Excellent support for standards (since v5)
  • Multi-language support, the official website can download dozens of languages.

 

 

 

 The picture above is the content of the rich text editor configured in the demand. My demand TinyMCE can be fully satisfied.

  TinyMCE official website: www.tiny.cloud

 

   TinyMCE supports vue, react, angular 

 

 This modified project uses react,

Encapsulated a rich text editing component suitable for us in the demand:

 

 

The contents of the editor component:

import React from 'react';
import './Editor.scss';

import {isDev, nginxPrefix} from '@/config';

import {Upload, Button, Icon, Popconfirm, Spin, message} from 'antd';

import _get from 'lodash/get';
import _uniqueId from 'lodash/uniqueId';

import PropTypes from 'prop-types';


* @ props object uploadConfig? Custom upload configuration
* @props function onAdd? add event
* @props function onDelete? delete event
* @props boolen disabled? disabled
* @props string defaultContent? initial content
* @props number height? height
* @props string id? identifier/ *
* @event function getEditorContent Get edit content 
* @event function setEditorContent Set edit content 
* @event function insertContent Insert edit content 
* / 
class Editor extends React.Component { 
    constructor (props) { 
        super (props); 

        const tinymceId = `editor-tinymce -$ { this .props.id}-$ {_ uniqueId ()}-$ { new Date (). getTime ()} `; 

        this .state = {
             // Editor ID 
            tinymceId,
             // Editor instance 
            editor: null 
        }; 
    } 

    componentDidMount () { 
        const {height= 300, defaultContent = ''} = this.props;
        window.tinymce.init({
            selector: `#${this.state.tinymceId}`,
            language: 'zh_CN',
            height: height,
            min_height: 200,
            width: '100%',
            resize: true,
            default_link_target: '_blank',
            init_instance_callback: editor => {
                if (defaultContent) {
                    editor.setContent(defaultContent);
                }
            },
            paste_enable_default_filters: true,
            // paste_word_valid_elements: () => {
            //
            // },
            // 插件配置
            plugins: 'table image lists link paste',
            // 菜单配置
            menubar: 'file edit view insert format',
            // 工具栏配置
            /* eslint-disable */
            toolbar: 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | outdent indent | blockquote | table | image link | forecolor backcolor | bullist numlist | removeformat'
            /*eslint-enable* / 
        }). then (([editor]) => this .setState ({editor})); 
    } 

    componentWillUnmount () { 
        // In some life cycles, the instance is not generated and there is no unmount method. (Component mounting phase) 
        // if (this.state.editor! == null) { 
        //      this.state.editor.destroy (); 
        // } window.tinymce.get 
        ( this .state.tinymceId) .destroy (); 
    } 

    getEditorContent = () => {
         return  this .state.editor.getContent (); 
    } 

    setEditorContent = (content) => { 
        window.tinymce.get ( this.state.tinymceId).setContent(content);
    }

    insertContent = (content) => {
        try {
            this.state.editor.insertContent(content);
        } catch(e) {
            window.tinymce.get(this.state.tinymceId).insertContent(content);
        }
    }

    // 默认上传配置
    uploadConfig = {
        name: 'file',
        action: (isDev ? '' : nginxPrefix) + '/admin/common/uploadFile',
        headers: {
            authorization: 'authorization-text',
        }, 
        onChange: (info) => {
             if (info.file.status === 'done' ) { 
                message.success ( 'Image upload successful' );
                 this .state.editor.insertContent ( 
                    ` <img src =" $ {_ get (info, 'file.response.data.result')} "> ` 
                ); 
            } else  if (info.file.status === 'error' ) { 
                message.error ( 'Image upload failed' ); 
            } 
        }, 
        accept: '.jpg, .jpeg, .jpe, .png, .bmp'
    }

    render() {
        const {uploadConfig} = this.props;
        return (
            <Spin spinning={this.props.disabled} indicator={<Icon type="stop" style={{color: '#555'}} />}>
                <div className="editor-container">
                    <textarea id={this.state.tinymceId} />
                    <div className="btn-bar">
                        <Upload {...(uploadConfig ? uploadConfig : this.uploadConfig)}>
                            <Button><Icon type="upload" />添加本地图片</Button>
                        </Upload>
                        <span>
                            {
                                this.props.onAdd
                                &&
                                <Button icon="plus" shape="circle" onClick={this.props.onAdd} />
                            }
                            {
                                this.props.onDelete
                                &&
                                <Popconfirm
                                    title="无法撤回,确认删除?"
                                    onConfirm={this.props.onDelete}
                                    okText="确认"
                                    cancelText="cancel"
                                    placement = "leftBottom" 
                                > 
                                    < Button 
                                        type = "danger" 
                                        icon = "delete" 
                                        shape = "circle" 
                                        style = {{marginLeft: '4px' }} 
                                        onClick = {() => {
                                             // When rich text editor When there is no content, the delete button does not pop up,Directly call the delete method 
                                            const content = this.getEditorContent();

                                            if (!content) {
                                                this.props.onDelete();
                                            }
                                        }}
                                    />
                                </Popconfirm>
                            }
                        </span>
                    </div>
                </div>
            </Spin>
        );
    }
}

Editor.defaultProps = {
    id: 'no-props-id',
    height: 300,
    defaultContent: '',
    onDelete: null,
    onAdd: null,
    disabled: false,
    uploadConfig: null
};

Editor.propTypes = {
    id: PropTypes.string,
    height: PropTypes.number,
    defaultContent: PropTypes.string,
    onDelete: PropTypes.func,
    onAdd: PropTypes.func,
    disabled: PropTypes.bool
};

export default Editor;

 

 

The component finally submits a piece of HTML, the picture is just a URL, the size is very small, very practical

In this demand, the rich text edit box is a case entry,

Of course, there is a display when you enter it, and it is also very simple for the display. A picture enlargement function is added to the display place

There is a problem when displaying, that is, the size of the picture we want to control is very small, so that the entire content can be seen, and the specific content of the picture can be clicked to enlarge

 

 

 

 

 

 

 

 

Come and show me the handsome picture after clicking the picture of my male god:

 

 

 

Guess you like

Origin www.cnblogs.com/katydids/p/12676111.html