富文本编辑器
在上一节中,我们介绍了使用 Tio Boot Admin、React 和 WangEditor 实现文章管理功能。本节将聚焦于富文本编辑器的功能扩展和使用,展示如何通过定制上传功能支持图片、视频和嵌入 YouTube 视频的能力。
富文本编辑器组件实现
编辑器组件 (CommonEditor.tsx
)
CommonEditor
是对 WangEditor 的封装,提供了文本编辑、图片和视频上传功能。以下是组件的实现代码:
import "@wangeditor/editor/dist/css/style.css";
import React, { useEffect, useState } from "react";
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
import { customUploadForEditor } from "@/services/system/systemService";
type CommonEditorProps = {
value?: string;
onChange: (editor: IDomEditor) => void;
};
const CommonEditor: React.FC<CommonEditorProps> = ({ value, onChange }) => {
const [editor, setEditor] = useState<IDomEditor | null>(null);
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {};
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
placeholder: "请输入内容...",
MENU_CONF: {},
};
// 图片上传配置
editorConfig.MENU_CONF["uploadImage"] = {
customUpload: customUploadForEditor, // 自定义上传逻辑
base64LimitSize: 5 * 1024, // 小于 5KB 的图片直接转为 Base64
};
// 视频上传配置
editorConfig.MENU_CONF["uploadVideo"] = {
customUpload: customUploadForEditor, // 自定义上传逻辑
};
// 销毁 editor 实例
useEffect(() => {
return () => {
if (editor) {
editor.destroy();
setEditor(null);
}
};
}, [editor]);
return (
<div style={{ border: "1px solid #ccc", zIndex: 100 }}>
<Toolbar
editor={editor}
defaultConfig={toolbarConfig}
mode="default"
style={{ borderBottom: "1px solid #ccc" }}
/>
<Editor
defaultConfig={editorConfig}
value={value}
onCreated={setEditor}
onChange={onChange}
mode="default"
style={{ height: "500px", overflowY: "hidden" }}
/>
</div>
);
};
export default CommonEditor;
自定义上传逻辑
在编辑器中,图片和视频的上传需要经过服务器校验并存储。以下是上传逻辑的实现:
上传服务 (systemService.ts
)
该服务包括以下功能:
- 文件的 MD5 校验:判断文件是否已存在,避免重复上传。
- 文件上传:如果文件不存在,则将其上传至服务器。
import { request } from "@umijs/max";
import crypto from "crypto";
// 计算文件的 MD5 哈希值
function calculateFileMd5(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function (event) {
if (event.target?.result) {
const arrayBuffer = event.target.result as ArrayBuffer;
const hash = crypto.createHash("md5").update(Buffer.from(arrayBuffer)).digest("hex");
resolve(hash);
} else {
reject(new Error("文件读取失败"));
}
};
reader.onerror = function (error) {
reject(error);
};
reader.readAsArrayBuffer(file);
});
}
// 校验文件是否存在
async function checkFileExistence(md5: string) {
return request<API.Result>(`/api/system/file/url?md5=${md5}`, { method: "GET" });
}
// 文件上传
async function uploadFile(category: string, file: File) {
const formData = new FormData();
formData.append("file", file);
formData.append("category", category);
return request<API.Result>("/api/system/file/upload", { method: "POST", data: formData });
}
// 编辑器的上传逻辑
export async function uploadForEditor(file: File) {
const md5 = await calculateFileMd5(file);
const response = await checkFileExistence(md5);
if (response.ok && response.data) {
return response;
} else {
return uploadFile("", file).then((response) => response);
}
}
// 自定义上传逻辑
export async function customUploadForEditor(file: File, insertFn: any) {
uploadForEditor(file).then((response) => {
if (response.ok) {
const url = response.data.url;
const alt = response.data.id;
insertFn(url, alt, url); // 插入图片或视频
} else {
insertFn("", "上传失败", "");
}
});
}
功能扩展
1. 添加图片
用户可通过工具栏的 图片上传 按钮选择本地图片文件,上传成功后自动插入图片至编辑器内容中。
- 工具栏位置:在富文本编辑器中,点击“图片上传”按钮。
- 效果:图片会以 URL 的形式插入到文档中。
2. 添加视频
支持通过工具栏的 视频上传 按钮插入本地视频。
- 工具栏位置:在富文本编辑器中,点击“视频上传”按钮。
- 效果:视频会以 URL 的形式嵌入到文档中。
3. 嵌入 YouTube 视频
通过编辑器的 视频插入功能,用户可以嵌入 YouTube 视频 iframe。
- 操作步骤:
- 点击 工具栏 > 视频 > 插入视频。
- 在弹出的输入框中粘贴以下代码:
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/8OQ6LdVYjRA"
title="YouTube 视频"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
- 效果:YouTube 视频将嵌入到编辑器内容中,用户可以直接预览。
总结
通过对 WangEditor 的扩展,富文本编辑器不仅支持基本的文本编辑,还实现了图片、视频的上传与管理,并支持嵌入第三方视频(如 YouTube)。这种灵活的扩展方式可以满足多场景需求,为内容创作提供了强大的工具支持。