一个 h5 页面编辑器。不同于使用绝对定位
布局的方式,h5-editor 使用了标准的文档流进行布局,减少关联组件之间定位所需要的各种计算,
使得组件之间父子级关系一目了然,整块操作(拖拽、锁定/解锁、统一样式设置)更为方便。使用 h5-editor,只需稍加熟悉,你便你能像专业前端开发者那样得心应手,创建出你想要的精美页面
目前 h5-editor 内有 8 个组件可供使用,其中 4 个基础组件,集成 4 个Vant(有赞) 组件,满足基本业务场景
- 所见即所得 - h5-editor 抽离了"解析器"组件,编辑和预览都是通过它解析,所以编辑器里是什么样,结果就是什么样
- 自定义组件 - 当你需要在不同页面频繁拖拽一个相同或者大致相同的组件时,可以右键选择
做成组件
功能,让该组件成为自定义组件,此后可以在左侧列表中拖拽复用,拒绝重复操作 - 样式继承 - 由于使用了标准文档流,你可以通过一个容器(div)组件预先设置好样式,其内部组件样式会默认继承该组件样式,拒绝重复操作
- 一键预览 - 右侧工具栏中点击
预览
可随时查看页面效果 - 自适应布局 - 预览器内部通过计算,将编辑时得到的
px
像素,转化为可自适应的rem
单位,实现不同分辨率端自适应 - 扫码或链接查看/分享 - 在文档库页面,可以通过扫码或访问链接的方式进行查看或分享
- 事件绑定 - 可以通过属性面板为组件绑定对应的事件并执行指定动作
- 支持接口数据源 - 可在数据源面板添加三方接口作为数据源
- 动态渲染变量 - 通过
{{数据源}}
的方式可以将数据源中的数据渲染到页面上
# 依赖安装
$ npm install
# 启动前端工程
$ npm run front-serve
# 启动后端接口服务
$ npm run back-server
$ npm run build
执行上述命令后会在根目录得到dist
文件夹,其中包含front
前端代码和server
后端代码
直接将打包后得到的front
目录部署到nginx
或其它服务器中,并将/api
和 /static
露路径代理到接口服务中,
可参照此nginx.conf配置文件
-
将打包后的
server
目录上传服务器 -
$ npm install --production
安装依赖 -
启动服务
-
推荐使用 pm2
$ pm2 start ecosystem.config.js
pm2 方式启动配置了监听文件变动重启,后续更新代码会自动重启
-
直接启动
$ node index.js
-
-
将执行完
build
后的到的dist
目录上传到服务器中 -
构建镜像
# 进入根目录 $ cd dist # 构建镜像 $ docker build -t h5editor .
-
启动容器
$ docker run -dit --name h5editor -v $PWD:/app -p 5000:80 h5editor
上述启动容器是在 dist 目录下进行的,即把 dist 目录挂载到容器中,随后文件变动/更新将同步到容器中 。 当然,服务端代码变动也会自动重启
前端采用vue3
+typescript
开发,并使用以下库
- element-plus 整个前端 UI 框架
- Vant 构建三方组件库
- html2canvas 文稿封面截图
- jsondiffpatch json 差异对比,h5-editor 通过
jsondiffpatch
进行差异对比,并通过差异进行patch
和unpatch
以实现撤销/重做 - axios http 请求
- qrcode 生成二维码
关于撤销/重做的实现逻辑可查看此文档
Component
:所有小组件的基类,开发组件需要继承它ComponentWrapper
:用来包裹组件,实现了点击、拖拽、缩放的功能性组件。任何组件都需要包裹在其中Container
:容器组件,类似于div
。Button
:按钮Img
:图片Text
:文本
NvaBar
:标题/导航栏NoticeBar
:通知栏Swiper
:轮播Tab
:标签页组件
后端采用 Express(4.x) + typescript
开发,并使用了如下库
- nedb-promises 以 json 文件本地存储的数据库
- ejs js 模板引擎,用于服务端渲染页面
文档数据存储在文件根目录data
目录中。备份迁移只需要此文件夹即可。容器挂载目录/app/data
启动后端接口时得到如下错误
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
遇到此问题,请在server/src/index.ts
中把设置模板引擎的代码随意换个位置即可,具体原因不详。
根据 express issue 中的解释 是因为未使用app.set
替代app.use
设置模板引擎
但是此项目中确实用的是app.set
却依旧报错。根据尝试只需要随意换个位置即可成功运行.
const compression = require('compression');
app.use(compression());
- app.set('view engine', 'ejs');
require('express-async-errors');
+ app.set('view engine', 'ejs');
app.all('*', function (req: Request, res: Response, next: NextFunction) {
感谢JetBrains提供的开源License