這周作了一個PC端的service後臺需求,要求有富文本編輯器,插入圖片、表格,字體字號背景色等等,css
最後引入了富文本編輯器TinyMCEvue
對於TinyMCE的簡介:react
TinyMCE是一款易用、且功能強大的所見即所得的富文本編輯器。同類程序有:UEditor、Kindeditor、Simditor、CKEditor、wangEditor、Suneditor、froala等等。nginx
TinyMCE的優點:antd
上圖爲需求中配置的富文本編輯器的內容,個人需求TinyMCE徹底能夠知足,編輯器
TinyMCE 官網:www.tiny.cloud工具
TinyMCE支持vue、react、angular 字體
此次改動的工程使用的是react,this
在需求中封裝了一個適合咱們的富文本編輯組件:spa
editor組件中的內容:
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 string id? 標識符 * @props number height? 高度 * @props string defaultContent? 初始內容 * @props boolen disabled? 禁用 * @props function onDelete? 刪除事件 * @props function onAdd? 添加事件 * @props object uploadConfig? 自定義上傳配置 * @event function getEditorContent 獲取編輯內容 * @event function setEditorContent 設置編輯內容 * @event function insertContent 插入編輯內容 */ class Editor extends React.Component { constructor(props) { super(props); const tinymceId = `editor-tinymce-${this.props.id}-${_uniqueId()}-${new Date().getTime()}`; this.state = { // 編輯器ID tinymceId, // 編輯器實例 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() { // 在某些生命週期中,實例並未生成,沒有卸載方法。(組件掛載階段) // 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('圖片上傳成功'); this.state.editor.insertContent( `<img src="${_get(info, 'file.response.data.result')}" >` ); } else if (info.file.status === 'error') { message.error('圖片上傳失敗'); } }, 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="取消" placement="leftBottom" > <Button type="danger" icon="delete" shape="circle" style={{marginLeft: '4px'}} onClick={() => { // 當富文本編輯器中沒有內容時,刪除按鈕不彈窗,直接調用刪除方法 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;
組件最終提交的是一段HTML,圖片只是一個URL,大小很是小,很是實用
此次的需求中富文本編輯框是錄入案例,
固然有錄入就有展現,對於展現也很簡單,在展現的地方加了個圖片放大的功能
展現的時候有個問題,就是圖片的大小咱們想控制的很小,這樣總體的內容均可以看到,圖片具體內容能夠點擊圖片放大,
來來來,展現一下我男神圖片點擊放大以後的帥圖: