原生HTML文档案例 wangEditor-master/packages/editor/demo/like-qq-docs.html
WangEdtior
import { useState, useEffect, useMemo } from 'react';import {string,number,object,array,func,oneOf,oneOfType} from "prop-types";import { merge, noop, isEqual } from "lodash-es";import cls from 'classnames';import { Editor, Toolbar } from '@wangeditor/editor-for-react';import {IDomEditor,IEditorConfig,IToolbarConfig} from '@wangeditor/editor';import Content from './Content';const ENUM_MODE = ["simple", "default"];WangEditor.propTypes = {value: oneOfType([array, string]),onChange: func,title: string,titleChange: func,height: number,placeholder: string,mode: oneOf(ENUM_MODE),className: oneOfType([string, object]),style: object,};WangEditor.defaultProps = {onChange: noop,titleChange: noop,height: 200,placeholder: "请输入内容...",mode: "simple"};function WangEditor(props) {const {value,onChange,title,titleChange,height,placeholder,mode,className,style} = props;// editor 编辑器实例const [editorInst, setEditorInst] = useState<IDomEditor | null>(null);// 编辑器内容const [content, setContent] = useState(value);// useEffect 是在render结束之后才执行的useEffect(() => {// 及时销毁 editorInst 重要!return () => {if (!editorInst) return;editorInst.destroy();setEditorInst(null);};}, [editorInst]);// value 改变,设置 contentuseEffect(() => {// 设置内容if (isEqual(value, content)) return;setContent(value);}, [value]);// 工具栏配置const toolbarConfig: Partial<IToolbarConfig> = useMemo(() => ({}), []);// 编辑器配置const editorConfig: Partial<IEditorConfig> = useMemo(() => ({placeholder,// scroll: false, // 禁止编辑器滚动// maxLength: 1000,// onMaxLength(editor) {// console.log('Trigger maxlength callback')// },MENU_CONF: {// onChange(editor: any) {// console.log(editor.getHtml());// },uploadImage: {// form-data fieldName ,默认值 'wangeditor-uploaded-image'fieldName: 'your-custom-name',// 单个文件的最大体积限制,默认为 2MmaxFileSize: 2 * 1024 * 1024, // 1M// 最多可上传几个文件,默认为 100maxNumberOfFiles: 10,// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []allowedFileTypes: ['image/*'],/*** 小于该值就插入 base64 格式(而不上传),默认为 0* 1MB 兆 = 1024KB 千字节 * 1024B 比特 = 1048576 kb 字节* 1MB = 1024KB* 1KB = 1024B* 10 * 1024 * 1024, // 10M 以下插入 base64*/// 10 * 1024 * 1024 // 10M 以下base64LimitSize: 5 * 1024, // 5kb// 跨域是否传递 cookie ,默认为 falsewithCredentials: true,// 超时时间,默认为 10 秒timeout: 5 * 1000, // 5 秒// 自定义增加 http headerheaders: {Accept: 'text/x-json',otherKey: 'xxx',},// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。meta: {token: 'xxx',otherKey: 'yyy',},},// fontSize: { // 覆盖默认的配置// fontSizeList: [// { name: '26px', value: '26px' },// ],// }}}), [placeholder]);// 编辑器内容改变function handleChange(editor: IDomEditor) {// const html = editor.getHtml(); // 获取 HTML// const text = editor.getText(); // 获取纯文本,默认带换行符// const text = editor.getText().replace(/\n|\r/mg, '');const json = editor.children; // 获取 JSON []// editor.getSelectionText() // 选中的文字setContent(json);onChange(json, editor);}const EditorStyle = useMemo(() => {return merge({ height, overflow: "hidden auto" }, style);}, [style, height]);const isSimple = isEqual(mode, ENUM_MODE[0]);return (<div className={cls('z-100', {__simple__: isSimple,}, className)}>{/*工具栏组件*/}<Toolbareditor={editorInst}defaultConfig={toolbarConfig}mode={mode}/><Contentvalue={title}onChange={titleChange}isSimple={isSimple}>{/*编辑器组件*/}<EditordefaultConfig={editorConfig}content={content}onCreated={setEditorInst}// 编辑器内容改变onChange={handleChange}style={EditorStyle}mode={mode}/></Content></div>);}export default WangEditor;
Content.tsx
/*** @author lulongwen* Date: 2023-08-20 21:50* Description:*/import { memo, useState, useEffect } from 'react';import { string, func, node, bool } from 'prop-types';import cls from 'classnames';import styles from "./style.module.less";Content.propTypes = {value: string,onChange: func.isRequired,children: node,isSimple: bool,};function Content(props) {const {value,onChange,children,isSimple,} = props;// 标题const [title, setTitle] = useState(value);useEffect(() => {// 设置标题if (value === title) return;setTitle(value);}, [value]);// 标题组件表单改变function inputChange(e) {const inputValue = e.target.value;setTitle(inputValue);onChange(inputValue);}if (isSimple) {return children;}return (<div className={styles.editor}><section className={styles.area}><header className={cls('py-3', styles.border)}><inputvalue={title}type="text"placeholder='请输入标题'className='w-full border-none text-3xl outline-none'onChange={inputChange}/></header>{children}</section></div>);}export default memo(Content);
style.module.less
/*** @author lulongwen* Date: 2023-02-04 22:53* Update: 2023-08-20 20:30:41* Description:*/.editor {position: relative;height: calc(100% - 50px);background-color: rgb(245, 245, 245);overflow-y: auto;}.area {width: 70%;min-height: 900px;margin: 24px auto 120px;padding: 16px 24px 24px;border: 1px solid #e8e8e8;background-color: #fff;box-shadow: 0 2px 10px rgb(0 0 0 / 8%);.border {border-bottom: 1px solid #e8e8e8;}}
