1、前端封装WangEditor富文本编辑器
-
参考官网文档 www.wangeditor.com/ , 然后 使用
npm install @wangeditor/editor-for-react --save
进行安装,然后封装成自定义组件,把html和setHtml暴露给父组件
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import React, { useState, useEffect } from "react";
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
function MyEditor({ html, setHtml }: any) {
// editor 实例
const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
// TS 语法
placeholder: "请输入内容...",
MENU_CONF: {
uploadImage: {
server: "/api/common/wang_editor/upload",
fieldName: "file",
},
},
};
// 及时销毁 editor ,重要!
useEffect(() => {
return () => {
if (editor == null) return;
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={html}
onCreated={setEditor}
onChange={(editor) => setHtml(editor.getHtml())}
mode="default"
style={{ height: "500px", overflowY: "hidden" }}
/>
</div>
</>
);
}
export default MyEditor;
2. 父组件使用富文本编辑器组件,添加表单项
<Form.Item label="详情" name="content">
<MyEditor html={html} setHtml={setHtml} />
</Form.Item>
3. 修改一下网络请求,在表单提交后,也将html富文本内容用content字段也一并提交给后端
onFinish={async (v) => {
console.log(currentId);
// 若有id则修改
if (currentId) {
const res = await fetch("/api/articles/" + currentId, {
method: "PUT",
body: JSON.stringify({ ...v, imageUrl, content: html }),
});
} else {
// 若无则新增
const res = await fetch("/api/articles", {
body: JSON.stringify({ ...v, imageUrl, content: html }),
method: "POST",
});
}
setQuery({ ...query });
setOpen(false);
}}
2、添加富文本编辑器上传本地图片功能
-
参考官方文档,www.wangeditor.com/v5/menu-con… , 添加编辑器配置,将server字段改成自己的图片上传接口,fileName改成对应接收的字段
// 编辑器配置 const editorConfig: Partial = { // TS 语法 placeholder: "请输入内容...", MENU_CONF: { uploadImage: { server: "/api/common/wang_editor/upload", fieldName: "file", }, }, };
-
准备后端接口,依旧是先保存图片到本地,然后根据官网配置,需要修改响应体格式,
import { NextRequest, NextResponse } from "next/server"; import path from "path"; import fs from 'fs' import { randomUUID } from "crypto"; // 文件保存 const saveFile = async (blob: File) => { const dirName =
/upload/${new Date().getFullYear()}-${new Date().getMonth() + 1}const uploadDir = path.join(process.cwd(), 'public' + dirName) // 上传路径 fs.mkdirSync(uploadDir,{recursive: true}) // 创建目录,有则创建 const fileName = randomUUID() + '.png' // 文件名 const arrayBuffer = await blob.arrayBuffer() fs.writeFileSync(uploadDir + '/' + fileName,new DataView(arrayBuffer)) // 将数据写入文件 return dirName + '/' + fileName }export const POST = async (req: NextRequest) => { const formData = await req.formData() // 获取formData的数据 const fileName = await saveFile(formData.get('file') as File) // 将文件数据存储 return NextResponse.json({ "errno": 0, // 注意:值是数字,不能是字符串 "data": { "url": fileName, // 图片 src ,必须 // "alt": "yyy", // 图片描述文字,非必须 // "href": "zzz" // 图片的链接,非必须 } } ) }
-
最后尝试在富文本编辑器中添加图片,然后查看接口,ok完成
3、最终富文本编辑器build时候会报错
-
因为富文本编辑器可能会用一些客户端功能函数,所以修改一下配置,不进行ssr渲染
-
这时要使用next的动态组件,然后关闭ssr
import dynamic from "next/dynamic"; const MyEditor = dynamic(() => import("../../_components/MyEditor"), { ssr: false, });
-
然后再build,完成
4、pm2部署nextjs项目
- 我们希望项目可以一直在后台运行,而不是关闭命令行就结束了,所以这里使用pm2进行进程守护,首先使用命令 npm i -g pm2进行全局安装
- 然后使用 pm2 ls可以查看当前进程
- 我们在当前项目下使用命令, pm2 start npm --name 指定进程名字 -- start
- 这里使用