react项目封装富文本编辑器

一、富文本组件封装

1、安装依赖
  • yarn add react-quill 富文本依赖
  • yarn add quill-emoji 表情依赖
2、引入依赖
// react-quill 富文本依赖样式
import ReactQuill, { Quill } from 'react-quill';
import 'react-quill/dist/quill.snow.css';

// quill-emoji 表情依赖样式
import quillEmoji from 'quill-emoji';
import "quill-emoji/dist/quill-emoji.css";

const { EmojiBlot, ShortNameEmoji, ToolbarEmoji, TextAreaEmoji } = quillEmoji;

Quill.register({
    'formats/emoji': EmojiBlot,
    'modules/emoji-shortname': ShortNameEmoji,
    'modules/emoji-toolbar': ToolbarEmoji,
    'modules/emoji-textarea': TextAreaEmoji,
    // 'modules/ImageExtend': ImageExtend, //拖拽图片扩展组件
}, true);
3、创建class组件
  • value 富文本回显的内容
  • onChange 通过函数传给父组件的值
// 父子组件通信参数
interface Props {
    value: string  // 回显的传入的value
    onChange: (value: string) => void // 通过参数传给父组件的值
}

class ReactQuillWrap extends Component<Props, any>{
    reactQuillRef: any = null;
    // 自定义工具栏
    modules: any = {
        toolbar: {
            container: []
        }
    }

    constructor(props: any) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <ReactQuill
                value={this.props.value}
                modules={this.modules}
                ref={(el) => { this.reactQuillRef = el }}
                onChange={this.props.onChange.bind(this)}
            />
        )
    }
}

export default ReactQuillWrap;
4、配置自定义的工具栏
    modules: any = {
        toolbar: {
            container: [
                [{ 'size': ['small', false, 'large', 'huge'] }], //字体设置
                // [{ 'header': [1, 2, 3, 4, 5, 6, false] }], //标题字号,不能设置单个字大小
                ['bold', 'italic', 'underline', 'strike'],
                [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }],
                ['link', 'image'], // a链接和图片的显示
                [{ 'align': [] }],
                [{
                    'background': ['rgb(  0,   0,   0)', 'rgb(230,   0,   0)', 'rgb(255, 153,   0)',
                        'rgb(255, 255,   0)', 'rgb(  0, 138,   0)', 'rgb(  0, 102, 204)',
                        'rgb(153,  51, 255)', 'rgb(255, 255, 255)', 'rgb(250, 204, 204)',
                        'rgb(255, 235, 204)', 'rgb(255, 255, 204)', 'rgb(204, 232, 204)',
                        'rgb(204, 224, 245)', 'rgb(235, 214, 255)', 'rgb(187, 187, 187)',
                        'rgb(240, 102, 102)', 'rgb(255, 194, 102)', 'rgb(255, 255, 102)',
                        'rgb(102, 185, 102)', 'rgb(102, 163, 224)', 'rgb(194, 133, 255)',
                        'rgb(136, 136, 136)', 'rgb(161,   0,   0)', 'rgb(178, 107,   0)',
                        'rgb(178, 178,   0)', 'rgb(  0,  97,   0)', 'rgb(  0,  71, 178)',
                        'rgb(107,  36, 178)', 'rgb( 68,  68,  68)', 'rgb( 92,   0,   0)',
                        'rgb(102,  61,   0)', 'rgb(102, 102,   0)', 'rgb(  0,  55,   0)',
                        'rgb(  0,  41, 102)', 'rgb( 61,  20,  10)']
                }],
                [{
                    'color': ['rgb(  0,   0,   0)', 'rgb(230,   0,   0)', 'rgb(255, 153,   0)',
                        'rgb(255, 255,   0)', 'rgb(  0, 138,   0)', 'rgb(  0, 102, 204)',
                        'rgb(153,  51, 255)', 'rgb(255, 255, 255)', 'rgb(250, 204, 204)',
                        'rgb(255, 235, 204)', 'rgb(255, 255, 204)', 'rgb(204, 232, 204)',
                        'rgb(204, 224, 245)', 'rgb(235, 214, 255)', 'rgb(187, 187, 187)',
                        'rgb(240, 102, 102)', 'rgb(255, 194, 102)', 'rgb(255, 255, 102)',
                        'rgb(102, 185, 102)', 'rgb(102, 163, 224)', 'rgb(194, 133, 255)',
                        'rgb(136, 136, 136)', 'rgb(161,   0,   0)', 'rgb(178, 107,   0)',
                        'rgb(178, 178,   0)', 'rgb(  0,  97,   0)', 'rgb(  0,  71, 178)',
                        'rgb(107,  36, 178)', 'rgb( 68,  68,  68)', 'rgb( 92,   0,   0)',
                        'rgb(102,  61,   0)', 'rgb(102, 102,   0)', 'rgb(  0,  55,   0)',
                        'rgb(  0,  41, 102)', 'rgb( 61,  20,  10)']
                }],
                ['clean'], //清空
                ['emoji'], //emoji表情,设置了才能显示
                ['video2'], //我自定义的视频图标,和插件提供的不一样,所以设置为video2
            ],
            handlers: {
                'image': this.imageHandler.bind(this), //点击图片标志会调用的方法
            },
        },
        // ImageDrop: true,
        'emoji-toolbar': true,  // 是否展示出来
        "emoji-textarea": false, // emoji是否展示在文本框
        "emoji-shortname": true,
    }
5、上传图片方法
    imageHandler() {
        const input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', 'image/*');
        input.click();
        input.onchange = () => {
            const file = input.files ? input.files[0] : '';
            const fd = new FormData();
            fd.append('file', file);
            // const hide = message.loading('上传中...', 0);
            uploadSubmit(getSellerId(), fd).then((res: any) => {
                console.log('res===', res)
                if (res?.code === '0') {
                    let quill = this.reactQuillRef.getEditor(); // 获取到编辑器本身
                    const cursorPosition = quill.getSelection().index; // 获取当前光标位置
                    quill.insertEmbed(cursorPosition, "image", res.url); // 插入图片 
                    quill.setSelection(cursorPosition + 1); // 光标位置加1
                    // hide();
                }
            });
        };
    }

二、父组件使用

1、引入封装的组件
import ReactQillWrap from 'components/reactQuill';
2、render渲染
  • content 富文本内容回显值
  • setFieldsValue 设置表单值
  • handleChange 接收子组件的富文本内容
// 数据回显
componentDidMount() {
    const currentItem = this.props.current;
    if (currentItem) {
        this.form.current?.setFieldsValue({
            name: currentItem.name,
            content: currentItem.content
        })
    }
}

// 接收子组件的值
handleChange(value: string) {
    this.setState({ content: value })
}

// 表单嵌套
<Form.Item label="公司内容" name="content" initialValue="" rules={[{ required: true }]}>
    <ReactQillWrap value={this.state.content} onChange={this.handleChange.bind(this)} />
</Form.Item>
3、视图

在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值