注: 实现环境 React, 需要自行引入 wangeditor 、 jquery 、 antd(可以不用,图标自行替换)

父组件

  1. import React, { Component } from 'react'
  2. import Editor from './Editor'
  3. class XXX extends Component {
  4. constructor(props) {
  5. super(props)
  6. this.state = {
  7. html: '' // 富文本内容
  8. }
  9. this.editorRef = React.createRef()
  10. }
  11. /** 主动获取富文本编辑器内容 */
  12. getEditorContent() {
  13. try {
  14. return this.editorRef.current.editor.txt.html()
  15. } catch (error) {
  16. throw (error)
  17. }
  18. }
  19. render() {
  20. return (
  21. <Editor ref={ this.editorRef } editorContent={ this.state.html }></Editor>
  22. )
  23. }
  24. }
  25. export default XXX

子组件(富文本)

  1. /*
  2. * @Author: baolong
  3. * @Date: 2020-03-13 16:23:22
  4. * @LastEditors: OBKoro1
  5. * @LastEditTime: 2020-03-18 09:56:18
  6. * @FilePath: /intellect-cs/src/views/KnowledgeBase/Knowledge/EditKnowledge/Editor.js
  7. * @Description: 富文本编辑器
  8. */
  9. import React, { Component } from 'react'
  10. import E from 'wangeditor'
  11. import $ from 'jquery'
  12. import './fullScreen/index.less'
  13. import { Icon } from 'antd'
  14. import {
  15. buildPreviewHtml
  16. } from './config'
  17. export default class Editor extends Component {
  18. constructor(props) {
  19. super(props)
  20. this.state = {
  21. editorContent: '',
  22. oldPropsEditorContent: '', // 存储上一状态导入的文件内容,判断数据是否改变
  23. editor: null
  24. }
  25. this.editor = null
  26. this.editorTabsRef = React.createRef()
  27. this.editorContentRef = React.createRef()
  28. }
  29. componentDidMount() {
  30. const that = this
  31. // eslint-disable-next-line react/no-string-refs
  32. const editorTabsRef = this.editorTabsRef.current
  33. const editorContentRef = this.editorContentRef.current
  34. /** 工具栏和内容分开生成 */
  35. this.editor = new E(editorTabsRef, editorContentRef)
  36. // 自定义处理粘贴的文本内容
  37. this.editor.customConfig.uploadImgShowBase64 = true
  38. // 自定义菜单配置
  39. this.editor.customConfig.menus = [
  40. 'undo', // 撤销
  41. 'redo', // 重复
  42. 'fontSize', // 字号
  43. 'foreColor', // 文字颜色
  44. 'bold', // 粗体
  45. 'italic', // 斜体
  46. 'underline', // 下划线
  47. 'strikeThrough', // 删除线
  48. 'emoticon', // 表情
  49. 'link', // 插入链接
  50. 'list', // 列表
  51. 'justify', // 对齐方式
  52. 'quote', // 引用
  53. 'image', // 插入图片
  54. 'table', // 表格
  55. 'code' // 插入代码
  56. // 'fontName', // 字体
  57. // 'video', // 插入视频
  58. // 'backColor', // 背景颜色
  59. // 'head', // 标题
  60. ]
  61. this.editor.create()
  62. /** 全屏 */
  63. $('#fullScreen').on('click', function() {
  64. $('.editorID').toggleClass('fullscreen-editor')
  65. if ($('#fullScreen').attr('type') === 'fullscreen') {
  66. $('#fullScreen').attr('type', 'fullscreen-exit')
  67. } else {
  68. $('#fullScreen').attr('type', 'fullscreen')
  69. }
  70. })
  71. /** 预览 */
  72. $('#preview').on('click', function() {
  73. if (window.previewWindow) {
  74. window.previewWindow.close()
  75. }
  76. window.previewWindow = window.open()
  77. window.previewWindow.document.write(buildPreviewHtml(that.editor.txt.html()))
  78. window.previewWindow.document.close()
  79. })
  80. }
  81. componentDidUpdate() {
  82. if (this.state.oldPropsEditorContent !== this.props.editorContent) {
  83. let content = this.props.editorContent
  84. /** wangEditor不支持id内容大写,所以需要替换一下 */
  85. content = content.replace(/id="A"/ig, `id="content"`)
  86. content = content.replace(/#A/ig, `#content`)
  87. this.editor.txt.html(content.replace(/id="A"/ig, `id="content"`))
  88. this.setState({
  89. oldPropsEditorContent: this.props.editorContent
  90. })
  91. }
  92. }
  93. render() {
  94. return (
  95. // eslint-disable-next-line react/no-string-refs
  96. <div className='editorID'>
  97. <div className='tools' ref={ this.editorTabsRef } style={{ textAlign: 'left' }}>
  98. {/** 全屏按钮 */}
  99. <div className='w-e-menu'>
  100. <Icon id='fullScreen' type='fullscreen' />
  101. </div>
  102. {/** 预览按钮 */}
  103. <div className='w-e-menu'>
  104. <a id='preview' className='_wangEditor_btn_fullscreen'>预览</a>
  105. </div>
  106. </div>
  107. <div className='content' ref={ this.editorContentRef } style={{ textAlign: 'left' }}></div>
  108. </div>
  109. )
  110. }
  111. }

全屏样式文件 ./fullScreen/index.less

  1. .w-e-toolbar {
  2. flex-wrap: wrap;
  3. -webkit-box-lines: multiple;
  4. }
  5. .w-e-toolbar .w-e-menu:hover {
  6. z-index: 10002 !important;
  7. }
  8. .w-e-menu a {
  9. text-decoration: none;
  10. }
  11. .fullscreen-editor {
  12. position: fixed !important;
  13. width: 100% !important;
  14. height: 100% !important;
  15. left: 0px !important;
  16. top: 0px !important;
  17. background-color: white;
  18. z-index: 9999;
  19. &.editorID .content {
  20. max-height: 100%;
  21. }
  22. }
  23. .fullscreen-editor .w-e-text-container {
  24. width: 100% !important;
  25. height: 95% !important;
  26. }

预览框架文件 .config.js

  1. /** 富文本组件创建预览页面配置 */
  2. export const buildPreviewHtml = (html) => {
  3. return `
  4. <!Doctype html>
  5. <html>
  6. <head>
  7. <title>Preview Content</title>
  8. <style>
  9. html,body{
  10. height: 100%;
  11. margin: 0;
  12. padding: 0;
  13. overflow: auto;
  14. background-color: #f1f2f3;
  15. }
  16. .container{
  17. box-sizing: border-box;
  18. width: 1000px;
  19. max-width: 100%;
  20. min-height: 100%;
  21. margin: 0 auto;
  22. padding: 30px 20px;
  23. overflow: hidden;
  24. background-color: #fff;
  25. border-right: solid 1px #eee;
  26. border-left: solid 1px #eee;
  27. }
  28. .container img,
  29. .container audio,
  30. .container video{
  31. max-width: 100%;
  32. height: auto;
  33. }
  34. .container p{
  35. white-space: pre-wrap;
  36. min-height: 1em;
  37. }
  38. .container pre{
  39. padding: 15px;
  40. background-color: #f1f1f1;
  41. border-radius: 5px;
  42. }
  43. .container blockquote{
  44. margin: 0;
  45. padding: 15px;
  46. background-color: #f1f1f1;
  47. border-left: 3px solid #d1d1d1;
  48. }
  49. </style>
  50. </head>
  51. <body>
  52. <div class="container">${ html }</div>
  53. </body>
  54. </html>
  55. `
  56. }

所用富文本插件 wangEditor3