工作中遇到了一个需要做图文详情 的富文本编辑的需求, 于是基于 React-draft-wysiwyg 实现了一个 纯组件, 目前支持 常规文本输入 外部链接图片 以即本地上传图片, 由于是纯组件, 可直接放在react 项目中引入使用, 就不废话了 直接上代码
import React, { Component } from 'react'; import { Editor } from 'react-draft-wysiwyg'; import { EditorState, convertToRaw, ContentState } from 'draft-js'; import draftToHtml from 'draftjs-to-html'; import htmlToDraft from 'html-to-draftjs'; import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'; // 这里的 UploadBase64 是我的图片上传接口 import { UploadBase64 } from '@/services/common_services'; // 这里的 IMG_URL 图片的 Host, 因为上面的接口上传成功返回的是一个相对路径 页面展示时需要自行拼接 Host。 这两处, 大家可根据实际情况自行修改 import { IMG_URL } from '@/utils'; const transformDraftStateToHtml = (editorState) => { if (!editorState.getCurrentContent) { return ''; } return draftToHtml(convertToRaw(editorState.getCurrentContent())); }; const transformHtmlToDraftState = (html = '') => { const blocksFromHtml = htmlToDraft(html); const { contentBlocks, entityMap } = blocksFromHtml; const contentState = ContentState.createFromBlockArray(contentBlocks, entityMap); return EditorState.createWithContent(contentState); } class EditorVan extends Component { state = { editorState: '' } onEditorStateChange = (editorState) => { this.setState({ editorState }) this.props.transformHTML( transformDraftStateToHtml(editorState) ) }; componentDidMount() { this.setState({ editorState: transformHtmlToDraftState(this.props.editorState) }) }; uploadImageCallBack = (file) => { return new Promise((resolve, reject) => { (async() => { const base64 = await getBase64(file); const data = { base64: base64.split(',')[1], fileName: file.name, fileCode: 'material', } const res = await UploadBase64(data); if(res && res.data) { resolve({ data: { link: `${IMG_URL}${res.data}`, }, }); } else { reject(); } })(); }) } render() { return ( <Editor editorState={this.state.editorState} onEditorStateChange={this.onEditorStateChange} toolbar={{ image: { uploadCallback: this.uploadImageCallBack, alt: { present: true, previewImage: true }, previewImage: true, }, }} /> ) } }; export default EditorVan; function getBase64(img, callback) { return new Promise((res, rej) => { const reader = new FileReader(); reader.addEventListener('load', () => res(reader.result)); reader.readAsDataURL(img); }) }