注: 实现环境 React, 需要自行引入 wangeditor 、 jquery 、 antd(可以不用,图标自行替换)
父组件
import React, { Component } from 'react'
import Editor from './Editor'
class XXX extends Component {
constructor(props) {
super(props)
this.state = {
html: '' // 富文本内容
}
this.editorRef = React.createRef()
}
/** 主动获取富文本编辑器内容 */
getEditorContent() {
try {
return this.editorRef.current.editor.txt.html()
} catch (error) {
throw (error)
}
}
render() {
return (
<Editor ref={ this.editorRef } editorContent={ this.state.html }></Editor>
)
}
}
export default XXX
子组件(富文本)
/*
* @Author: baolong
* @Date: 2020-03-13 16:23:22
* @LastEditors: OBKoro1
* @LastEditTime: 2020-03-18 09:56:18
* @FilePath: /intellect-cs/src/views/KnowledgeBase/Knowledge/EditKnowledge/Editor.js
* @Description: 富文本编辑器
*/
import React, { Component } from 'react'
import E from 'wangeditor'
import $ from 'jquery'
import './fullScreen/index.less'
import { Icon } from 'antd'
import {
buildPreviewHtml
} from './config'
export default class Editor extends Component {
constructor(props) {
super(props)
this.state = {
editorContent: '',
oldPropsEditorContent: '', // 存储上一状态导入的文件内容,判断数据是否改变
editor: null
}
this.editor = null
this.editorTabsRef = React.createRef()
this.editorContentRef = React.createRef()
}
componentDidMount() {
const that = this
// eslint-disable-next-line react/no-string-refs
const editorTabsRef = this.editorTabsRef.current
const editorContentRef = this.editorContentRef.current
/** 工具栏和内容分开生成 */
this.editor = new E(editorTabsRef, editorContentRef)
// 自定义处理粘贴的文本内容
this.editor.customConfig.uploadImgShowBase64 = true
// 自定义菜单配置
this.editor.customConfig.menus = [
'undo', // 撤销
'redo', // 重复
'fontSize', // 字号
'foreColor', // 文字颜色
'bold', // 粗体
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'emoticon', // 表情
'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
'image', // 插入图片
'table', // 表格
'code' // 插入代码
// 'fontName', // 字体
// 'video', // 插入视频
// 'backColor', // 背景颜色
// 'head', // 标题
]
this.editor.create()
/** 全屏 */
$('#fullScreen').on('click', function() {
$('.editorID').toggleClass('fullscreen-editor')
if ($('#fullScreen').attr('type') === 'fullscreen') {
$('#fullScreen').attr('type', 'fullscreen-exit')
} else {
$('#fullScreen').attr('type', 'fullscreen')
}
})
/** 预览 */
$('#preview').on('click', function() {
if (window.previewWindow) {
window.previewWindow.close()
}
window.previewWindow = window.open()
window.previewWindow.document.write(buildPreviewHtml(that.editor.txt.html()))
window.previewWindow.document.close()
})
}
componentDidUpdate() {
if (this.state.oldPropsEditorContent !== this.props.editorContent) {
let content = this.props.editorContent
/** wangEditor不支持id内容大写,所以需要替换一下 */
content = content.replace(/id="A"/ig, `id="content"`)
content = content.replace(/#A/ig, `#content`)
this.editor.txt.html(content.replace(/id="A"/ig, `id="content"`))
this.setState({
oldPropsEditorContent: this.props.editorContent
})
}
}
render() {
return (
// eslint-disable-next-line react/no-string-refs
<div className='editorID'>
<div className='tools' ref={ this.editorTabsRef } style={{ textAlign: 'left' }}>
{/** 全屏按钮 */}
<div className='w-e-menu'>
<Icon id='fullScreen' type='fullscreen' />
</div>
{/** 预览按钮 */}
<div className='w-e-menu'>
<a id='preview' className='_wangEditor_btn_fullscreen'>预览</a>
</div>
</div>
<div className='content' ref={ this.editorContentRef } style={{ textAlign: 'left' }}></div>
</div>
)
}
}
全屏样式文件 ./fullScreen/index.less
.w-e-toolbar {
flex-wrap: wrap;
-webkit-box-lines: multiple;
}
.w-e-toolbar .w-e-menu:hover {
z-index: 10002 !important;
}
.w-e-menu a {
text-decoration: none;
}
.fullscreen-editor {
position: fixed !important;
width: 100% !important;
height: 100% !important;
left: 0px !important;
top: 0px !important;
background-color: white;
z-index: 9999;
&.editorID .content {
max-height: 100%;
}
}
.fullscreen-editor .w-e-text-container {
width: 100% !important;
height: 95% !important;
}
预览框架文件 .config.js
/** 富文本组件创建预览页面配置 */
export const buildPreviewHtml = (html) => {
return `
<!Doctype html>
<html>
<head>
<title>Preview Content</title>
<style>
html,body{
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
background-color: #f1f2f3;
}
.container{
box-sizing: border-box;
width: 1000px;
max-width: 100%;
min-height: 100%;
margin: 0 auto;
padding: 30px 20px;
overflow: hidden;
background-color: #fff;
border-right: solid 1px #eee;
border-left: solid 1px #eee;
}
.container img,
.container audio,
.container video{
max-width: 100%;
height: auto;
}
.container p{
white-space: pre-wrap;
min-height: 1em;
}
.container pre{
padding: 15px;
background-color: #f1f1f1;
border-radius: 5px;
}
.container blockquote{
margin: 0;
padding: 15px;
background-color: #f1f1f1;
border-left: 3px solid #d1d1d1;
}
</style>
</head>
<body>
<div class="container">${ html }</div>
</body>
</html>
`
}
所用富文本插件 wangEditor3