amis-editor+React 18
react.js - react集成amis(低代码)保姆级教程 - 个人文章 - SegmentFault 思否
这次又接手一个掉头发的需求,在react项目中实现低代码表单可视化编辑,最终在领导“高明(没钱买)”的调研下,选择了百度的开源amis产品,至于为啥用react,这是甲方的爹要求的,非我等喽啰可以决定
起步
- 项目是搭建好了架子交给我的,在之前项目已经实现了基础的后台管理系统该有的功能,我拿着一脸懵,因为之前一段时间一直开发的项目都是vue2或vue3,并且该项目使用vite作为编译工具
- 从项目熟悉开始,打开package.json看里面的依赖,然后看路由,看axios封装文件,慢慢熟悉项目
安装amis-editor
- 目标明确,跳过amis,直接弄amis-editor,打开文档不知道是我自己蠢逼的原因还是文档过于简单,安装完依赖后,按文档操作全是报错
- 其实这里完全按照文档操作会有问题
第一个坑
- 如果你只是安装了amis-editor,你会发现你根本无法打开,你还必须看文档的“快速开始”章节,安装mox等一系列依赖,但是文档中好像并未在明显地方提及
第二个坑
- 光是
npm i mox ...
还是不行,因为amis兼容mox的版本在4.x.x,如果版本高了依旧会报错,所以记录好版本
npm install mobx@4.15.7 mobx-react@6.3.1 mobx-state-tree@3.17.3 --legacy-peer-deps
- 这样安装完应该是正确的版本
第三个坑
- 样式问题:我的解决方式是把官方demo的代码拉到本地,把它所有的样式文件全部拷贝到我的项目中
- 但是还是无法避免的有问题,比如高度没有限制,导致整个页面变得很长,不符合需求
.Editor-Demo{
.Editor-inner {
position: relative;
flex: 1 1 auto;
overflow-x: hidden;
overflow-y: auto;
.ae-Editor {
height: 100%;
}
}
}
- 找了许久,发现是内部容器没有限制,所以限制一下
目前
- 到目前为止,项目能正常操作,但是控制台还有很多很多报错,所以会有后续内容
- 目前代码
import { Card, message } from "antd";
import { Editor, ShortcutKey } from "amis-editor";
import { useState, useEffect } from "react";
import { useSearchParams, useNavigate } from "react-router-dom";
import { useAliveController } from "react-activation";
export default function TestAmis() {
const [messageApi, contextHolder] = message.useMessage();
const [preview, setPreview] = useState(true);
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const { dropScope } = useAliveController();
const [initialSchema, setInitialSchema] = useState({
type: "page",
title: "新增表单",
body: []
});
const id = searchParams.get("id");
useEffect(() => {
id && getDetail();
}, [id]);
const getDetail = async () => {
const { data } = await getObj(id!);
setInitialSchema(JSON.parse(data.formValue));
};
const onChange = (value: any) => {
setInitialSchema(value);
};
const onSubmit = async () => {
const params = {
id,
formName: initialSchema.title,
formValue: JSON.stringify(initialSchema)
};
id ? await editObj(params) : await addObj(params);
messageApi.open({
type: "success",
content: `${id ? "修改" : "新增"}成功`,
duration: 2,
onClose: async () => {
let url = `/teamWork/formManage`;
await dropScope("formManage");
navigate(url);
}
});
};
return (
<>
{contextHolder}
<Card>
{/* <h1>AMIS 编辑器</h1> */}
<div className="Editor-Demo">
<div className="Editor-header">
<div className="Editor-title">amis 可视化编辑器</div>
<div className="Editor-view-mode-group-container">
<div className="Editor-view-mode-group">
<div className={`Editor-view-mode-btn editor-header-icon is-active`}>
{/* <Icon icon="pc-preview" title="PC模式" /> */}
pc模式
</div>
<div className={`Editor-view-mode-btn editor-header-icon`}>
{/* <Icon icon="h5-preview" title="移动模式" /> */}
移动模式
</div>
</div>
</div>
<div className="Editor-header-actions">
<ShortcutKey />
<div
className={`header-action-btn m-1 ${preview ? "primary" : ""}`}
onClick={() => {
setPreview(!preview);
}}
>
{preview ? "编辑" : "预览"}
</div>
<div className={`header-action-btn exit-btn`} onClick={onSubmit}>
保存
</div>
</div>
</div>
<div className="Editor-inner">
<Editor value={initialSchema} onChange={onChange} />
</div>
</div>
</Card>
</>
);
}