集成 ant design 上传组件
集成 ant design 上传组件逻辑参考 braft.margox.cn/demos/antd-… , 该组件更主要的是把editorState, setEditorState通过useImperativeHandle暴露给父组件。
import { forwardRef, useImperativeHandle } from 'react';
import BraftEditor, { ControlType, ExtendControlType } from 'braft-editor';
import { useState } from 'react';
import { Upload as AntdUpload } from 'antd';
import { ContentUtils } from 'braft-utils';
import Message from '../Library/Message';
import './index.less';
export const BraftEditorInstance = BraftEditor;
export default forwardRef(function HWBraftEditor(props, ref) {
const [editorState, setEditorState] = useState(BraftEditor.createEditorState(null));
const controls: ControlType[] = [
'font-size',
'bold',
'italic',
'underline',
'text-color',
'text-align',
'separator',
'link',
'separator',
];
// 将 editorState 和更新 editorState 的方法暴露给父组件,父组件就无需每次使用时创建
// useImperativeHandle api 可自定义暴露组件内部的方法,但需要配合forwardRef使用
useImperativeHandle(
ref,
() => ({
editorState,
setEditorState,
}),
[editorState],
);
const onUploadChange = ({ file, fileList }) => {
if (file.status === 'done') {
setEditorState(
ContentUtils.insertMedias(editorState, [
{
type: 'IMAGE',
url: file.response.data,
},
]),
);
}
};
const beforeUpload = (file) => {
if (file.size > 5 * 1024 * 1024) {
Message.error('上传文件不能超过50M');
return false;
}
};
// TODO
const uploadProps = {
name: 'image',
action: `${API_PREFIX}/api/back/OssImage`,
headers: {
token: localStorage.getItem('backToken') || '',
},
onChange: onUploadChange,
beforeUpload,
};
const handleChange = (editorState) => {
setEditorState(editorState);
};
const extendControls: ExtendControlType[] = [
{
key: 'antd-uploader',
type: 'component',
component: (
<AntdUpload accept={'.jpg,.jpeg,.png,.gif'} showUploadList={false} {...uploadProps}>
<button type='button' className='control-item button upload-button' data-title='插入图片'>
插入图片
</button>
</AntdUpload>
),
},
];
return (
<BraftEditor
value={editorState}
onChange={handleChange}
controls={controls}
extendControls={extendControls}
/>
);
});
编辑页中使用 BraftEditor
父组件通过暴露的方法更新或者提交表单,而不用每次都创建editorState, setEditorState,达到简化使用的目的。
import { useParams } from 'umi';
import { useEffect, useRef } from 'react';
import { Button, Form, Space } from '@/components/Library';
import { Container } from '@/components/Dashboard';
import BraftEditor, { BraftEditorInstance } from '@/components/BraftEditor';
import request from '@/api';
import urlMap from '@/api/url-map';
const { articleManage } = urlMap;
export default function AddArticle() {
const id = Number(useParams().id);
const [form] = Form.useForm();
const editorRef = useRef<any>(null);
const onFinish = (values: any) => {
// 提交表单时转为HTML格式
values.content = editorRef.current.editorState.toHTML();
};
useEffect(() => {
// 获取详情
request.get(articleManage.detail, { postId: id }).then((res) => {
res.data.content = BraftEditorInstance.createEditorState(res.data.content);
editorRef.current.setEditorState(res.data.content); // 给受控富文本组件赋值
// initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新
form.setFieldValue('content', res.data.content);
});
}, []);
return (
<Container>
<Form
name='basic'
labelCol={{ span: 3 }}
wrapperCol={{ span: 12 }}
form={form}
onFinish={onFinish}
autoComplete='off'
>
<Form.Item label='内容' name='content'>
<BraftEditor ref={editorRef} />
</Form.Item>
<Form.Item wrapperCol={{ offset: 3 }}>
<Space>
<Button onClick={() => history.back()}>取消</Button>
<Button type='primary' htmlType='submit'>
保存
</Button>
</Space>
</Form.Item>
</Form>
</Container>
);
}