Braft Editor 是基於draft-js開發的富文本編輯器,適用於 React 框架。css
npm install braft-editor --save
yarn add braft-editor
import React, { Component } from 'react' import BraftEditor from 'braft-editor' import 'braft-editor/dist/index.css' export default class Main extends Component { state = { editorState: BraftEditor.createEditorState('<p>初始值</p>'), // 設置編輯器初始內容 outputHTML: '<p></p>' // 編輯器輸出內容 } componentDidMount () { this.setState({ editorState: BraftEditor.createEditorState('<p>hello,<b>world!</b><p>') }) } handleChange = (editorState) => { this.setState({ editorState: editorState, outputHTML: editorState.toHTML() }, () => { console.log(editorState) console.log(this.state.outputHTML) }) } render () { const { editorState, outputHTML } = this.state return ( <div> <div className="editor-wrapper"> <BraftEditor value={editorState} onChange={this.handleChange} /> </div> </div> ) } }
Braft Editor使用 controls 屬性指定須要展現的控件;使用contentStyle調整編輯區域的高度。react
render () { const controls = [ 'undo', 'redo', 'separator', 'font-size', 'line-height', 'letter-spacing', 'separator', 'text-color', 'bold', 'italic', 'underline', 'strike-through', 'separator', 'superscript', 'subscript', 'remove-styles', 'emoji', 'separator', 'text-indent', 'text-align', 'separator', 'headings', 'list-ul', 'list-ol', 'blockquote', 'code', 'separator', 'link', 'separator', 'hr', 'separator', 'media', 'separator', 'clear' ] return ( <div className="editor-wrapper"> <BraftEditor controls={controls} contentStyle={{height: 210, boxShadow: 'inset 0 1px 3px rgba(0,0,0,.1)'}} /> </div> ) }
Braft Editor上傳圖片會默認轉成base64, 下面將使用Ant Design 的上傳組件改爲上傳到服務器的方法:npm
yarn add braft-utils
import React, { Component } from 'react' import BraftEditor from 'braft-editor' import 'braft-editor/dist/index.css' export default class Main extends Component { state = { editorState: BraftEditor.createEditorState(null) } componentDidMount () { this.setState({ editorState: BraftEditor.createEditorState('<p>hello,<b>world!</b><p>') }) } onOk = () => { this.props.form.validateFields((err, fieldsValue) => { if (!err) { console.log(fieldsValue) } }) } beforeUpload = file => { this.props.form.setFieldsValue({ content: ContentUtils.insertMedias(this.props.form.getFieldValue('content'), [{ type: 'IMAGE', url: imgUrl, // imgUrl 爲上傳成功後 後臺返回的url地址 }]) return false } render () { const { form: { getFieldDecorator }, } = this.props const { editorState } = this.state const formItemLayout = { labelCol: { sm: { span: 4 }, }, wrapperCol: { sm: { span: 20 }, }, } const controls = [ 'undo', 'redo', 'separator', 'font-size', 'line-height', 'letter-spacing', 'separator', 'text-color', 'bold', 'italic', 'underline', 'strike-through', 'separator', 'superscript', 'subscript', 'remove-styles', 'emoji', 'separator', 'text-indent', 'text-align', 'separator', 'headings', 'list-ul', 'list-ol', 'blockquote', 'code', 'separator', 'link', 'separator', 'hr', 'separator', // 'media', 'separator', 'clear' ] const extendControls = [ { key: 'antd-uploader', type: 'component', component: ( <Upload accept="image/*" showUploadList={false} beforeUpload={this.beforeUpload} > {/* 這裏的按鈕最好加上type="button",以免在表單容器中觸發表單提交,用Antd的Button組件則無需如此 */} <button type="button" className="control-item button upload-button" data-title="插入圖片"> <Icon type="picture" theme="filled" /> </button> </Upload> ) } ] return ( <div> <div className="editor-wrapper"> <Form {...formItemLayout}> <Form.Item label="標題"> {getFieldDecorator(`title`, { initialValue: '', rules: [{ required: true, message: '請輸入標題' }], })( <Input placeholder="請輸入" allowClear style={{ width: 300 }} /> )} </Form.Item> <Form.Item label="內容"> {getFieldDecorator(`content`, { validateTrigger: 'onBlur', initialValue: editorState, rules: [{ required: true, message: '請輸入內容' }], })( <BraftEditor className={styles.editorStyle} contentStyle={{ height: 160, boxShadow: 'inset 0 1px 3px rgba(0,0,0,.1)' }} controls={controls} extendControls={extendControls} placeholder="請輸入正文內容" /> )} </Form.Item> <Form.Item> <Button type="primary" onClick={this.onOk}> 肯定 </Button> </Form.Item> </Form> </div> </div> ) } }