{"id":13522864,"url":"https://github.com/fantasticit/ramiko","last_synced_at":"2025-04-07T08:25:06.217Z","repository":{"id":37644614,"uuid":"274918976","full_name":"fantasticit/ramiko","owner":"fantasticit","description":"nextjs + nest.js 构建页面可视化编辑器 -- Ramiko","archived":false,"fork":false,"pushed_at":"2023-03-08T00:32:28.000Z","size":1721,"stargazers_count":303,"open_issues_count":6,"forks_count":49,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-31T06:08:51.709Z","etag":null,"topics":["h5","reactjs","visual","visualization"],"latest_commit_sha":null,"homepage":"http://124.221.147.83:4002/editor","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fantasticit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-06-25T13:08:35.000Z","updated_at":"2024-12-18T11:29:57.000Z","dependencies_parsed_at":"2023-01-27T19:16:13.328Z","dependency_job_id":"6b6a542a-864f-45d4-89c3-6973e3d96bb9","html_url":"https://github.com/fantasticit/ramiko","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fantasticit%2Framiko","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fantasticit%2Framiko/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fantasticit%2Framiko/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fantasticit%2Framiko/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fantasticit","download_url":"https://codeload.github.com/fantasticit/ramiko/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247616821,"owners_count":20967480,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["h5","reactjs","visual","visualization"],"created_at":"2024-08-01T06:00:53.094Z","updated_at":"2025-04-07T08:25:06.191Z","avatar_url":"https://github.com/fantasticit.png","language":"TypeScript","funding_links":[],"categories":["实战项目","TypeScript","![Open Source Love svg3](https://badges.frapsoft.com/os/v3/open-source.svg?v=103)"],"sub_categories":["低代码项目"],"readme":"# next.js + nest.js 构建页面可视化编辑器 -- Ramiko\n\n## 前言\n\n最近看了不少关于 h5 页面制作工具。端午闲来无事，决定尝试下一个页面搭建工具。效果如下：\n\n![](https://wipi.oss-cn-shanghai.aliyuncs.com/2020-06-28/QQ20200628-105408-HD.gif)\n![](https://wipi.oss-cn-shanghai.aliyuncs.com/2020-06-27/ramiko-ditor.png)\n![](https://wipi.oss-cn-shanghai.aliyuncs.com/2020-06-27/ramiko-page.png)\n\ngif 录制效果不佳，可以访问以下链接进行体验。\n\n- Github：[传送门](https://github.com/fantasticit/ramiko)\n- 编辑器：[传送门](http://124.221.147.83:4002/editor)\n\n## 技术栈\n\n- next.js：前端模块化开发\n- sass: 配合使用 css modules\n- nest.js：服务端语言\n- MySQL：数据存储\n\n## 整体架构\n\n![](https://wipi.oss-cn-shanghai.aliyuncs.com/2020-06-28/ramiko-jiagou.png)\n\n前端开发组件库，完善组件类型，编辑器读取组件完成页面搭建，将页面数据发送至服务端保存。\n访问页面，从服务端拉取页面数据，前端渲染页面即可。\n\n## 编辑器设计\n\n![编辑器整体结构图](https://wipi.oss-cn-shanghai.aliyuncs.com/2020-06-28/ramiko.png)\n\n```shell\n.\n|____index.tsx\n|____plugins               ## 组件库管理\n|____Editor.tsx            ## 编辑器\n|____type.ts               ## 类型定义\n|____components\n| |____Pannel              ## 左侧组件面板\n| |____Preview             ## 中间预览面板\n| |____Editor              ## 组件编辑器实现\n| | |____index.tsx\n| | |____PropsEditor\n| | | |____index.tsx\n| | | |____components\n| | | | |____SwitchEditor\n| | | | |____RadioEditor\n| | | | |____ImgEditor\n| | | | |____ColorEditor\n| | | | |____TextEditor\n| | | | |____TextareaEditor\n| | | | |____NumberEditor\n| | | |____renderEditorItem.tsx\n| | | |____UnionEditor.tsx\n| | |____FunctionEditor\n| | |____SettingEditor\n|____renderPage.tsx\n```\n\n## 数据结构\n\n### 定义页面数据结构\n\n既然是可视化页面搭建，那么页面必须可以以某种数据结构进行描述。比如：\n\n```js\n{\n  setting: {\n  } // 页面设置\n  components: []; // 页面使用到的组件\n}\n```\n\n### 定义组件数据结构\n\n页面核心是由组件搭建而成的，那么就要定义组件的数据结构。\n\n```tsx\nimport React from 'react';\n\nexport const Title = ({ title, style }) =\u003e {\n  return \u003ch1\u003e{title}\u003c/h1\u003e;\n};\n\nTitle.defaultProps = {\n  title: '标题'\n};\n\nTitle.schema = {\n  title: {\n    title: '标题',\n    type: 'text'\n  }\n};\n```\n\n核心可以抽象为：\n\n```js\n{\n  name: 'Title'; // 对应组件名\n  props: {\n  }\n  schema: {\n  }\n}\n```\n\n#### `name`\n\n不可能把组件源代码保存到服务端，所以这里只保存组件的名称，前端渲染时，根据该名称找到对应组件渲染即可（类似 Vue.js 的动态组件）\n\n#### `props`\n\nReact 组件的 props，这里使用 `defaultProps` 赋值默认值\n\n#### `schema`\n\n对应 `props` 各个属性的描述，用于编辑器针对进行渲染。进行组件编辑，实际上编辑的是组件的 `props`，`props` 改变组件的渲染结果自然改变。为了对 `props` 进行编辑，需要定义 `props` 的描述语言，通过 `props` 描述来进行属性编辑。这里使用如下的 `schema`。\n\n```js\n{\n  title: '标题';\n  type: 'text';\n}\n```\n\n对应组件 `props.title`，通过 `type` 可以决定如何渲染编辑器组件。\n\n## 无渲染组件\n\n可能光能渲染组件是不够的，也许需要更多的功能包装，比如埋点。这一类函数本质上也是组件。可以通过 `schema` 定义进行 `props` 编辑。举个例子：\n\n```js\nimport React from 'react';\n\nexport const Tracking = ({ op, pageSn, pageElSn, children }) =\u003e {\n  const onClick = () =\u003e {\n    alert('埋点测试：' + op + '_' + pageSn + '_' + pageElSn);\n  };\n\n  return \u003cdiv onClick={onClick}\u003e{children}\u003c/div\u003e;\n};\n\nTracking.defaultProps = {\n  op: 'click',\n  pageSn: null,\n  pageElSn: null\n};\n\nTracking.schema = {\n  op: {\n    title: '曝光方式',\n    type: 'radio',\n    options: ['click', 'pv']\n  },\n  pageSn: {\n    title: '页面编号',\n    type: 'number'\n  },\n  pageElSn: {\n    title: '元素编号',\n    type: 'number'\n  }\n};\n```\n\n## 丰富完善\n\n1. 丰富组件库\n2. 优化编辑器：比如添加组件拖拽功能。\n\n## 项目启动\n\nGithub：[传送门](https://github.com/fantasticit/ramiko)\n\n在 `client` 和 `server` 分别执行 `yarn dev` 即可。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffantasticit%2Framiko","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffantasticit%2Framiko","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffantasticit%2Framiko/lists"}