This commit is contained in:
parent
8f9c9fc6a1
commit
14004b9022
14
src/common/components/Editor/custom-types.d.ts
vendored
Normal file
14
src/common/components/Editor/custom-types.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { SlateDescendant } from '@wangeditor/editor';
|
||||
|
||||
declare module '@wangeditor/editor' {
|
||||
// 扩展 Text
|
||||
interface SlateText {
|
||||
text: string;
|
||||
}
|
||||
|
||||
// 扩展 Element
|
||||
interface SlateElement {
|
||||
type: string;
|
||||
children: SlateDescendant[];
|
||||
}
|
||||
}
|
||||
113
src/common/components/Editor/index.tsx
Normal file
113
src/common/components/Editor/index.tsx
Normal file
@ -0,0 +1,113 @@
|
||||
import { Apis } from '@/gen/Apis';
|
||||
import { IDomEditor, IToolbarConfig } from '@wangeditor/editor';
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
|
||||
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
|
||||
import axios from 'axios';
|
||||
import { useEffect, useState } from 'react';
|
||||
type InsertFnType = (url: string) => void;
|
||||
function MyEditor(props: any) {
|
||||
// editor 实例
|
||||
const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
|
||||
|
||||
// 编辑器内容
|
||||
const [html, setHtml] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setHtml(props.value || '');
|
||||
}, 500);
|
||||
}, []);
|
||||
|
||||
// 工具栏配置
|
||||
const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
|
||||
// const toolbarConfig = { } // JS 语法
|
||||
const customRequest = (
|
||||
file: any,
|
||||
onSuccess: (url: string, file: any) => void,
|
||||
) => {
|
||||
Apis.Auth.PreUpload({
|
||||
filename: file.name,
|
||||
alc: 'public-read',
|
||||
}).then(async (res) => {
|
||||
axios
|
||||
.put(res.data.url, file, {
|
||||
headers: res.data.headers,
|
||||
onUploadProgress: ({ total, loaded }) => {
|
||||
console.log('loaded', total, loaded);
|
||||
},
|
||||
})
|
||||
.then(({ data: response }) => {
|
||||
console.log('response', response);
|
||||
if (response.errorMessage) {
|
||||
console.log(response, file);
|
||||
} else {
|
||||
onSuccess(res.data.url.split('?')[0], file);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
abort() {
|
||||
console.log('upload progress is aborted.');
|
||||
},
|
||||
};
|
||||
};
|
||||
// 编辑器配置
|
||||
const editorConfig: Partial<any> = {
|
||||
// TS 语法
|
||||
// const editorConfig = { // JS 语法
|
||||
placeholder: '请输入内容...',
|
||||
MENU_CONF: {
|
||||
uploadVideo: {
|
||||
async customUpload(file: File, insertFn: InsertFnType) {
|
||||
// TS 语法
|
||||
customRequest(file, (url) => {
|
||||
console.log(url, '视频');
|
||||
insertFn(url);
|
||||
});
|
||||
},
|
||||
},
|
||||
uploadImage: {
|
||||
async customUpload(file: File, insertFn: InsertFnType) {
|
||||
// TS 语法
|
||||
customRequest(file, (url) => {
|
||||
console.log(url, '图片');
|
||||
insertFn(url);
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// 及时销毁 editor ,重要!
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (editor === null) return;
|
||||
editor.destroy();
|
||||
setEditor(null);
|
||||
};
|
||||
}, [editor]);
|
||||
|
||||
return (
|
||||
<div style={{ border: '1px solid #ccc', zIndex: 100 }} key="Editor">
|
||||
<Toolbar
|
||||
editor={editor}
|
||||
defaultConfig={toolbarConfig}
|
||||
mode="default"
|
||||
key="Toolbar"
|
||||
style={{ borderBottom: '1px solid #ccc' }}
|
||||
/>
|
||||
<Editor
|
||||
defaultConfig={editorConfig}
|
||||
value={html}
|
||||
key="Editor2"
|
||||
onCreated={setEditor}
|
||||
onChange={(editor) => props?.onChange?.(editor.getHtml())}
|
||||
mode="default"
|
||||
style={{ height: '500px', overflowY: 'hidden' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MyEditor;
|
||||
Loading…
x
Reference in New Issue
Block a user