CntChen / cntchen.github.io

CntChen Blog
https://github.com/CntChen/cntchen.github.io/issues
732 stars 64 forks source link

页面可视化搭建工具技术要点 #17

Open CntChen opened 5 years ago

CntChen commented 5 years ago

页面可视化搭建工具技术要点

背景

页面可视化搭建工具, 是互联网公司中常见的运营工具, 实现了运营人员快速生成和发布页面, 提升页面上线效率; 且无需开发人员介入, 节省开发人力.

页面可视化搭建工具搭建出的页面示例:

但从零开始设计和开发出这种工具并不简单. 笔者维护的页面可视化搭建框架 pipeline, 提供了页面可视化搭建的核心功能, 免去从零实现页面可视化搭建工具的困难.

本文主要包含以下内容:

活动页面开发之痛

活动页面特点

前端业务中, 经常需要开发产品介绍页/营销页/活动页/图片展示页等页面. 这类需求有以下几个特点:

活动页面常规开发流程

活动页面常规开发流程图

image

流程

  1. 运营/产品提出页面需求.
  2. 走项目流程进入开发环节.
  3. 开发根据设计稿完成页面开发.
  4. 测试进行页面测试.
  5. 运维进行页面上线.
  6. 运营/产品进行页面验收.

痛点

更优的流程

对于高频和重复的活动页面开发, 业界一般将页面做成配置化, 配置工作从开发人员交接给产品/运营等需求方; 开发和设计人员只需提供配置化页面支持. 更优的活动页面生成流程依靠页面可视化搭建系统来实现. 现.

更优的活动页面开发流程图

image

流程

  1. 运营/产品提出页面需求.
  2. 运营/产品在页面可视化搭建系统中选取合适的页面模板进行页面搭建.
  3. 页面自动化发布上线, 页面需求完成, 流程完结.
  4. 如果运营/产品没有找到合适的模板.
  5. 开发进行页面模板开发, 并将页面模板添加到页面可视化搭建系统中.
  6. 运营/产品继续流程2.

同时, 随着页面可视化搭建系统中的页面模板不断丰富, 新的页面需求对开发人员的依赖逐渐减低, 可由运营/产品直接完成.

页面可视化搭建工具

更优的活动页面开发流程依靠页面可视化搭建系统实现, 重点是要有页面可视化搭建工具提供技术支持. 页面可视化搭建工具通过填写配置数据表单, 拖拉页面组件等可视化的页面编辑方式, 实现页面的生成或修改.

但从零开始设计和开发出页面可视化搭建工具并不简单, 有几个需要了解和关注的技术点.

页面可视化搭建工具的技术要点

从技术角度, 设计和开发一个页面可视化搭建工具时, 需要考虑以下几个技术要点:

image

页面组件化

组件化的优点

页面的基本单元是 HTML 元素, 但是 HTML 元素无法包含业务逻辑, 且由 HTML 元素直接组合出页面, 过于繁杂和低效.

image 图片来源: https://vuejs.org/images/components.png

页面较好的组织方式是组件化, 如上图所示. 组件是对 HTML 元素、元素布局和样式、业务逻辑的封装. 通过组件封装业务逻辑, 并通过组件属性(Props)向外暴露组件的配置字段. 采用页面组件化, 复杂的页面可视化搭建可以转化为2个较简单的操作:

页面前端框架

页面组件化需依靠前端框架来实现. 页面可视化搭建工具的架构方式对页面前端框架有限制: 需选择页面可视化搭建工具支持的前端框架. 如: 页面可视化搭建工具只支持基于 vue 的页面, 那页面组件化的前端框架只能选择 vue.

但是前端技术团队选用的前端框架, 一般已用于支持现有业务, 并沉淀了一定数量的技术组件和业务组件. 如果需要针对页面可视化搭建工具进行前端框架的切换, 成本将会很大.

所以理想的页面可视化搭建工具, 应该和页面的前端框架解偶, 如下图所示. 技术团队在某前端框架中沉淀的技术组件和业务组件, 可在页面可视化搭建工具的页面中复用.

image

技术难点1:页面可视化搭建工具与页面前端框架解偶.

当然, 前端业务已选用了某前端框架, 开发专门支持该前端框架的页面可视化搭建工具, 也是高效实现目标的选择.

页面模板

页面模板包含完整的业务逻辑, 有助于快速生成业务页面. 不同的页面模板适用于不同的业务功能, 从模板库中选择合适的页面模板并派生出默认业务页面, 再对默认页面进行可视化编辑, 从而生成目标业务页面.

image

云凤蝶的页面模板列表: image 图片来源: https://www.yunfengdie.com/

模板带有页面的默认数据; 对于组件化的页面, 模板是从组件库中选取部分组件, 并带有各个组件的默认配置数据.

image

如上图所示, 页面组件库中有组件A, 组件B, 组件C, 组件D, ..., 组件X等. 页面模板一由组件库中的组件A, 组件B和组件C组成, 实现了一个完整的业务功能; 页面模板二由组件库中的组件A, 组件B和组件X组成, 完成另一个完整的业务功能.

页面编辑

页面由页面组件组合而成, 页面的编辑其实是对页面组件进行重新组合, 并编辑各页面组件的内容. 页面编辑包含2个部分: 编辑页面组件和编辑页面内容.

编辑页面组件

组件树

使用组件化的方式来组织页面, 页面可以认为是一棵组件树, 如下图所示, 树中的节点为页面组件, 页面组件可以包含子组件.

image

在代码编写上, 通过组件标签的组合来声明一棵组件树, 并在打包时生成页面资源, 在运行时加载页面资源渲染出页面.

react 和 vue 的组件树声明示例: image

编辑页面组件的一个可行方式是: 动态地给页面源码添加组件, 然后重新打包生成页面. 如通过可视化的方式替换 Left组件NewLeft组件 后, 对源码的组件树声明做替换, 将 Left 标签替换为 NewLeft 标签.

image

image

动态组件

一些前端框架支持动态组件, 可以根据组件树声明动态渲染出组件, 而无需在构建前就定义好页面的组件树结构. 对动态组件页面实现可视化组件编辑时, 可以只编辑组件树声明文件, 然后将组件树声明传入提前打包好的页面中进行渲染. 采用动态组件可以避免重新打包的耗时, 快速生成新页面.

Vue 根据组件树声明动态地渲染组件示例如下图, vue 动态组件使用 compontent 关键字来声明, 并通过 is 属性来决定实例化的具体组件. 对于 react, 组件是一个 js 对象, 直接在 jsx 中按照组件名称返回对应组件就可以了.

image

编辑页面内容

组件化页面的页面内容编辑, 是对页面中各个组件的组件属性(Props)进行配置.

组件配置数据

一个组件包含组件属性(Props), 组件状态(State), 组件HTML模板(Template), 组件业务逻辑(Javascript), 组件样式布局(Style)等几个部分.

组件的配置数据通过组件暴露的 Props 注入到组件中, 在组件内部 Props 作为常量分发给 State, Template, Javascript, Style 等其他组件内容, 由组件内容渲染出视图.

image

组件差异化

组件是业务内容的呈现载体, 不同的业务内容, 封装在不同的业务组件中. 所以页面模板中的组件是差异化的, 差异点体现在组件的 Props, State, Template, Javascript, Style 等组件内容上. 在编辑不同组件内容时, 组件配置数据的数据结构是也是差异化的.

如下图示的页面包含3个组件: 头部组件, 间隔区组件和天气组件. 头部组件的配置数据为头部标题和头部图片等; 间隔去组件的配置数据为间隔提示文本等; 天气组件的配置数据为城市名称. 不同的组件需要不同的配置数据.

image

需要为各组件差异化的配置数据定义数据结构和字段类型, 理想的配置数据格式为 JSON, 因为其格式灵活, 支持数据嵌套, 且前端友好.

组件配置表单

页面可视化搭建工具的主要使用人员是运营/产品, 如果让运营/产品人员直接编辑文本格式的组件配置数据, 操作不友好并且容易出错. 需提供可视化的编辑方式 -- 使用 Form 表单来填入配置数据. Form 表单是页面中数据交互的基本形式, 非开发人员使用也没有技术门槛. 使用配置表单来填入配置数据有2个好处:

image

如上图所示, 由于组件配置数据的差异化, 组件配置表单也是差异化的, 需为组件库中的每个组件提供相应的配置表单. 如果为每个组件都编写一个表单页面, 工作量较大; 对于复杂的配置项, 表单页面的编写工作量可能会大于页面组件的开发工作量. 需要重点考虑提供配置表单的方式.

技术难点2: 如何用最简单的方式生成配置数据编辑表单.

组件层级关系

组件树定义了组件间父子兄弟的层级关系, 父子组件通过数据流和事件进行关联: 数据从父组件的 State 传递到子组件的 Props; 子组件的变更触发 Event 通知父组件.

image

层级关系对数据流和布局的影响

页面可视化搭建工具编辑组件树时, 会修改组件数据流. 而不同组件的 Props 和 State 是异构的, 在编辑组件树时, 需要处理不同组件产生层级关系后对数据流的影响. 如下图, 父组件的 State 只包含子组件A的 Props, 将子组件B挂载为父组件的子组件, 父组件没有子组件B的 Props, 会导致无法渲染子组件B.

image

同理, 不同的组件有不同的样式布局, 编辑组件树时, 需要处理不同组件产生层级关系后带来的布局影响.

image 图片来源: https://alligator.io/react/using-this-props-children/

如下图, 一个父组件为行内组件, 给其添加一个块级组件作为子组件, 渲染后可能会导致行内组件被块级组件撑开.

image

所以设计页面可视化搭建工具的组件树编辑功能时, 需要重点关注组件树的层级关系, 解决组件间数据依赖和组件间布局适配问题. 页面可视化搭建工具需要制订组件嵌套的规则和约束, 通过组件嵌套规则来确保可视化编辑后的组件树正常渲染.

技术难点3: 如何组织页面组件的层级关系.

使用组件嵌套的搭建工具示例: image 图片来源: https://github.com/jaweii/Vue-Layout

不嵌套的前端框架组件

可以想象, 组件的嵌套会加大页面可视化搭建工具的架构设计和开发难度.

我们注意到, 营销活动的主要平台是移动端, 移动端页面的常用的布局策略是: 宽度铺满, 高度滚动. 如果前端框架组件都设置为铺满宽度, 页面展示时组件只需在浏览器垂直方向上顺序排列, 则组件组合时不需要嵌套 -- 所有组件互为兄弟节点.

这种铺满页面宽度的组件, 非常适合搭建移动端页面的场景: 在承载页面逻辑的同时, 使得页面的编辑更加简单, 使用者只需处理组件的顺序, 无需处理组件的嵌套.

在移动端, 使用非嵌套组件层级规则的页面可视化搭建工具有: 阿里云凤蝶pipeline 等.

阿里云凤蝶图示: image

可视化搭建PC端中后台系统页面的工具, 同样可以采用不嵌套组件层级规则, 如阿里的飞冰:

image

页面预览

页面实时预览是页面可视化搭建工具的必要部分, 使用人员可以在通过页面预览来查看和验证可视化编辑的效果.

页面预览示例: image

用户的可视化编辑包括修改组件树和修改组件配置数据. 如下图, 用户修改页面后, 需要重新渲染页面组件, 得到新的预览页面.

image

实现页面预览有两种方式: 页面挂载后台渲染.

页面挂载

页面挂载指在编辑器前端页面的某个元素节点(div)上渲染出用户编辑的效果. 页面挂载流程图如下:

image

使用页面挂载的预览方式, 编辑器前端页面需要提供组件库组件渲染环境(组件库前端框架); 为实现前端渲染, 编辑器前端源码需引入组件库组件源码, 后续组件库更新, 编辑器需要同步更新. 页面挂载方式有以下特点:

后台渲染

后台渲染指在后台进行用户编辑结果页面的渲染和生成, 编辑器前端页面通过 iframe 加载和展示结果页面. 后台渲染流程图如下:

image

使用后台渲染的预览方式, 编辑器前端页面并不需要渲染组件库的组件; 甚至不需要组件源码, 只需知道各个组件的描述信息. 后台渲染有以下特点:

难点4: 如何实现组件库的快速后台渲染, 从而实现编辑器和组件库前端框架的分离.

页面构建

页面构建是组件化前端源码生成页面资源的必要环节: 在开发时需要进行开发构建来进行页面调试; 在可视化编辑后可能需要重新构建来生成预览页面; 在发布前需要进行生产构建.

在可视化搭建页面时需要“实时”预览, 要求页面页面构建效率高, 实现快速的构建和打包. 更进一步, 后台渲染其实和服务端渲染很像, 能否借鉴服务端渲染的技术思路.

自定义模板和组件开发

页面可视化搭建工具在业务中的落地, 需要根据不同的业务场景进行业务组件和页面模板的自定义开发. 这对页面可视化搭建工具提出3个要求:

理想的活动页面可视化搭建工具

页面可视化搭建工具, 需要对页面做一些约定和约束, 在可视化搭建时遵循工具约定和约束来编辑页面. 从页面可视化搭建工具的技术要点中, 可以归纳出活动页面可视化搭建工具的理想形态.

页面可视化搭建工具有不同的框架设计和实现方式, 不同的功能有不同的适用场景, 详细分类可以参考笔者以前的文章: 页面可视化搭建工具前生今世.

概述

运营页面搭建工具, 实现基于模板的页面生成; 将页面的逻辑功能封装在组件内, 声明页面配置数据并提供配置表单, 通过对配置表单的数据填充, 进行少量页面编辑就可以完成业务页面搭建.

image

不嵌套的组件

在编辑自由度的选择上, 选用不嵌套的组件.各组件铺满页面宽度, 在页面高度方向顺序排列.解决组件嵌套带来的数据流问题. 不嵌套的组件如下图各个红框框起来的部分所示.

image

配置表单自动生成

配置表单的作用是生成和约束 JSON 配置数据, 业界已有对 JSON 进行描述和自动生成表单的方案 -- JSON Schema. 按照 JSON Schema 规范对 JSON 数据进行描述, 可以动态渲染出配置表单; 且 JSON Schema 可以对编辑后的数据做格式校验, 避免编辑错误. 这比编写一个表单页面更加简单和高效.

image 图片来源: https://github.com/json-editor/json-editor

JSON Schema 的语法并不是很精简, 云凤蝶的 Schema 语法 等方案更简洁, 但是云凤蝶的语法没有开源的表单生成库支持, 在开源实践上还是 JSON Schema 最佳.

理想活动页面搭建工具特点

页面可视化搭建框架 Pipeline

简介

Pipeline 是一个开源的页面可视化搭建框架, 主要由笔者在维护. Pipeline 意为流水线, 期望 pipeline 像工厂流水线一样可以高效地组装活动页面.

所谓框架, 是它实现了页面可视化搭建的基本功能, 解决了页面可视化搭建的基本难点, 可以让开发者快速拥有页面搭建的能力, 并支持私有部署和二次开发.

项目信息:

功能 Demo

可视化编辑

demo

如动图所示, pipeline 的可视化编辑能力有:

组件编辑

dnd_demo

如动图所示, pipeline 的组件编辑能力有:

支持的前端框架

Pipeline 实现了编辑器和页面前端框架的分离, 可以支持不同的前端框架. 所谓支持的前端框架, 就是对某个前端框架按照 pipeline 的约束规则进行组件编辑方式和工程构建方式的改造, 使得前端框架页面可以在 pipeline 中可视化搭建.

目前已经支持 Vue, React, 和 Omi, 理论上可以支持任意前端框架.

image

框架特点

与云凤蝶的对比

阿里云凤蝶 是目前市场上可见中最棒的页面可视化搭建服务, pipeline 的很多方面和云凤蝶相似, 做个简单对比:

云凤蝶 pipeline
商业化解决方案, 直接可用 开源系统, 基础的页面搭建框架, 需要自行部署
生成的页面, 上传的图片等只能托管在阿里, 也限定域名 资源落地和周边功能需要自行搭建, 但是可以100%掌控所有资源
配置表单功能比较完善 配置表单比较基础, 需要提升
使用自定义的组件配置约束规则 使用通用的 JSON Schema 规范
模板前端框架采用 Nunjucks 前端框架采用没有约束, 已经支持 vue 和 react 等, 业务迁移成本低
隐藏了模板的构建处理过程, 提供制定的 IDE 采用 webpack 构建, 模板开发与正常前端项目开发一致
不支持自定义页面级别的配置项 支持自定义页面级别的配置项

总的来说: 云凤蝶是完整的商业化页面可视化搭建系统, 适合偏业务运营的公司; pipeline 是开源的页面可视化搭建框架, 适合需要自建页面可视化搭建系统且有技术人员支持的公司.

下一步工作

总结

本文讨论了活动页面开发的痛点, 总结出页可视化搭建工具的7个技术要点和4个技术难点, 并整理出理想的运营页面可视化搭建工具, 最后介绍页面可视化搭建框架 pipeline.

行文仓促, 对页面可视化搭建话题或开源项目 pipeline 感兴趣, 欢迎讨论.

References

[React — Dynamic Component Names with JSX]: https://medium.com/@Carmichaelize/dynamic-tag-names-in-react-and-jsx-17e366a684e9

EOF

yi-ge commented 5 years ago

受益匪浅,感谢作者!

Chersquwn commented 5 years ago

页面预览可以用你提到的两种方式的结合体,即iframe+dom挂载的方式,通过iframe来隔离框架样式上的问题,用postMessage来通信就好了,用后台实时渲染还是太占资源了

之前也弄过一版,但是只能处理纯静态的页面,最终还是倒在动态数据交互上😂

wufenfen commented 5 years ago

文章很赞,很详细。体验了一下Demo,每次提交配置需要等待很久的时间感觉有点闹心。

CntChen commented 5 years ago

哈 因为是提交到服务器进行后台渲染 而服务器是国外的单核512M内存的虚拟机 后续可能买台国内的云服务器

本地部署或内网部署很快的 @wufenfen

stormqx commented 5 years ago

看了写的几篇文章感觉很赞,有一些问题不知道你们是否有遇到过?

自动生成配置表单 感觉是非常重要,设计的不好开发配置表单组件的时间比开发一个前端组件时间还长...

  1. 你们有两个或两个以上表单项数据或者逻辑关联的需求么?感觉当多个表单项产生关联关系时,复杂度极度上升。
  2. 表单项的异步数据获得你们有做么?

此外,实时预览这个功能我也挺感兴趣的,但感觉挺耗性能的,我还要再调研一下方案😄。

CntChen commented 5 years ago

自动生成配置表单

  1. 表单项间的关联没做处理过. 比较期望的情况是配置项之间是正交的, 不会相互关联. 一些关联感觉可以在组件内维护关系, 不在配置项上维护. 比如姓名的姓氏和名字, 可以有两个配置项, 但其关系在组件内维护. 另一种情况, 数据就是有关联, 配置项A的输入影响配置项B的合法输入. 这种用JSON Schema 比较难覆盖, 不过 JSON Schema 支持多选一的配置项, 就是整个配置数据可以在多个数据结构中选一个.

  2. 表单项的异步数据获得是请求网络数据作为表单项吗,比如获取一个优惠券id, 然后填入表单中? 如果是这种场景, 很好做的, JSON Editor 会暴露表单的修改方法, 用一个浮层去加载需要的配置项值, 然后用修改方法修改配置项.

实时预览 实时预览用后台预览的方式, 最主要的是插入组件列表到页面中, 可以做到比较轻量的.

Shijiuwei commented 5 years ago

@CntChen 楼主的实践和文章都很赞,对于涉及的关键技术细节做了讲解,看了下demo,有几个问题请教楼主: 1、组件库 只考虑 Vue 模板的时候,是否可以所有模板公用一个组件库?而不是不同的模板组件库是独立的。 2、如果只使用 Vue 开发,编辑器里是否可以去掉支持其它框架的代码? 3、加一个页面管理功能(类似于用户中心功能,对创建的页面/项目进行管理等)进去的话,麻烦嘛? 谢谢楼主!

CntChen commented 5 years ago

@GangRock 好问题.

  1. 组件库是可以公用一个组件库的. 但是不同的业务页面需要多个模板, 抽出组件库后会维护稍微复杂一点. pipeline 最初就是组件库和页面模板分离的, 页面模板里面放组件列表, 没有组件源码. 公用组件库的好处是组件库升级, 所有页面模板都用到最新的组件库. 不好的点在于, 组件库升级后, 一些页面模板引用的组件可能还是旧的, 就无法再次编辑了.

  2. 编辑器已经是和前端框架无关了, 也是用 vue 开发的. 为了实现 react 的 SSR 依赖了 React, 但是不影响单纯用 vue 的场景.

  3. 页面管理功能我后续加上去哈. 不会很复杂, 添加个数据库表, 添加后台接口和前端页面.

Shijiuwei commented 5 years ago

页面预览可以用你提到的两种方式的结合体,即iframe+dom挂载的方式,通过iframe来隔离框架样式上的问题,用postMessage来通信就好了,用后台实时渲染还是太占资源了

之前也弄过一版,但是只能处理纯静态的页面,最终还是倒在动态数据交互上😂

楼主使用后端渲染页面主要处于编辑器与编写组件/模板的前端框架解耦。其实要解决样式污染的问题,方法很多。

stormqx commented 5 years ago

自动生成配置表单

  1. 表单项间的关联没做处理过. 比较期望的情况是配置项之间是正交的, 不会相互关联. 一些关联感觉可以在组件内维护关系, 不在配置项上维护. 比如姓名的姓氏和名字, 可以有两个配置项, 但其关系在组件内维护. 另一种情况, 数据就是有关联, 配置项A的输入影响配置项B的合法输入. 这种用JSON Schema 比较难覆盖, 不过 JSON Schema 支持多选一的配置项, 就是整个配置数据可以在多个数据结构中选一个.
  2. 表单项的异步数据获得是请求网络数据作为表单项吗,比如获取一个优惠券id, 然后填入表单中? 如果是这种场景, 很好做的, JSON Editor 会暴露表单的修改方法, 用一个浮层去加载需要的配置项值, 然后用修改方法修改配置项.

实时预览 实时预览用后台预览的方式, 最主要的是插入组件列表到页面中, 可以做到比较轻量的.

我抽空看一下json-editor的实现思路。其实我们用的不是json schema,而是xml + xsd,我们自己实现了一套表单生成库。

  1. 我们有些场景确实会有表单项数据关联的情况,而且这些表单项之间的关联关系不是强关联,可以无关联单独使用的。感觉这可能就需要给表单生成库加上数据流管理的能力了,感觉有点重。
  2. 异步数据的场景比如某个单选框的选项数据是从后端接口拉的数据,我们在考虑用一种统一的方式来支持这个功能,保证所有的表单项都具备这个异步数据获取能力。
  3. 我们这边的前端框架是weex,所以实时预览功能必须要后端预览的方案。着重考虑的点可能是通过iframe嵌套的方式带来的性能损耗是否能接受?因为我们搭建页面和前台页面都挺复杂的。
CntChen commented 5 years ago

@stormqx 你们已经做得很深入了啊.

  1. 这个点超出我的了解的范围, 倒是可以尝试一下.
  2. 应该是可以加的, 只要在配置数据提交前, 可以插入数据获取和填入等操作. 关键是设计插入点.
  3. weex不了解, 可以验证一下. 如果是内部服务的话, 请求量级应该还可以接受.
sisswul commented 5 years ago

最近正在研究这块东西,学到了很多

vin1992 commented 5 years ago

写的很好,对组件化编辑工具的 整体思路 有了更清晰的认识 和理解,点赞👍

xxs665 commented 5 years ago

受益匪浅 不过可以跟楼主讨论一下 组件可以直接使用vue组件来做,页面逻辑、样式、配置都写到vue组件里面去 这样可以支持编辑的时候,实时在页面渲染,通过store就可以实现 不过在生成页面的时候,需要做一层编译

CntChen commented 5 years ago

页面渲染的思路也是可以的. 就是会让编辑器和框架耦合, 用了Vue, 就没法切 React 等. 用后台渲染的话, 可以做到编辑器和前端框架无关, 可以支持非Vue的页面.

winyh commented 5 years ago

页面预览可以用你提到的两种方式的结合体,即iframe+dom挂载的方式,通过iframe来隔离框架样式上的问题,用postMessage来通信就好了,用后台实时渲染还是太占资源了

之前也弄过一版,但是只能处理纯静态的页面,最终还是倒在动态数据交互上😂

我也是卡在了业务逻辑,动态交互上,用React实现了可嵌套的可视化操作,但是组件里的业务逻辑好象只有手动编码的方式解决,你后来有解决思路吗?

winyh commented 5 years ago

哈 因为是提交到服务器进行后台渲染 而服务器是国外的单核512M内存的虚拟机 后续可能买台国内的云服务器

本地部署或内网部署很快的 @wufenfen

看过你前天在AlloyTeam 发的文章,很受益。有2点疑问: 1.用页面挂载的方式实现即时预览,为什么会污染编辑器界面?我用的react 实现的可视化编辑,预览的时候直接把组件树还原成组件渲染。用一个渲染路由挂载一个我的渲染数据,好像没发现有污染的问题,不知道是不是技术框架的区别? 2.你的页面里的业务逻辑怎么实现的?比如组件A里一个事件钩子需要操作组件B的一个Props属性,也就是数据流的控制了。虽然可以预先设想一些可能的业务逻辑,这种业务逻辑是千变万化的,不可能完全枚举。我做的就是把事件钩子渲染出来,让用户手动编码写自己的业务逻辑

我当前也在做可视化编辑工具,定位是用编辑器生成页面级别的组件聚合成的区块,用数据描述页面,最终用浏览器生成一个React.jsx 文件下载。放在工程目录里就可以直接渲染了。希望有机会能跟你交流下

SunXinFei commented 5 years ago

非常好的一篇前端可视化搭建工具的总结文章

CntChen commented 5 years ago

看过你前天在AlloyTeam 发的文章,很受益。有2点疑问: 1.用页面挂载的方式实现即时预览,为什么会污染编辑器界面?我用的react 实现的可视化编辑,预览的时候直接把组件树还原成组件渲染。用一个渲染路由挂载一个我的渲染数据,好像没发现有污染的问题,不知道是不是技术框架的区别? 2.你的页面里的业务逻辑怎么实现的?比如组件A里一个事件钩子需要操作组件B的一个Props属性,也就是数据流的控制了。虽然可以预先设想一些可能的业务逻辑,这种业务逻辑是千变万化的,不可能完全枚举。我做的就是把事件钩子渲染出来,让用户手动编码写自己的业务逻辑

我当前也在做可视化编辑工具,定位是用编辑器生成页面级别的组件聚合成的区块,用数据描述页面,最终用浏览器生成一个React.jsx 文件下载。放在工程目录里就可以直接渲染了。希望有机会能跟你交流下

不好意思, 最近有点忙, 回复晚了.

  1. 页面挂载的主要缺点是编辑器和组件库耦合, 编辑器和组件库前端框架耦合. 样式污染问题可能会发生, 应该是小概率场景. 比如没有用 css scope, 并且给某个基础 css 选择器写了样式, 那这个 css 样式对编辑器页面也是生效的. 不过我没有实际实验这样的场景.
  2. 在我的实现中, 组件的业务逻辑是内聚的, 一个组件铺满页面宽度, 业务逻辑包含在组件内部. 在数据流方面, 并没有实现跨组件的数据流处理.

比如组件A里一个事件钩子需要操作组件B的一个Props属性, 我觉得通用组件的设计并不一定要有这样的功能, 这也不是页面搭建工具需要解决的通用问题, 这是一个具体业务问题. 组件A需要操作组件B的Props属性, 具体场景的A和B是特定业务组件, 比如优惠券组件需要去头像组件里取用户名, 那这个问题应该由优惠券组件和头像组件去约定和解决, 比如在全局对象挂属性和函数, 或通过发布订阅事件来实现等. 业务逻辑是需要具体业务场景去实现的, 我觉得不需要去枚举, 提供一个事件中心应该就差不多了, 具体组件可以订阅事件, 在事件中做逻辑处理, 由外部触发事件. 而组件是由一波开发人员开发出来的, 不会存在不了解组件有什么事件的情况. 对大部分可视化搭建工具, 逻辑部分其实是不适合通过可视化实现的. 更加简单的方式是提前定义好, 或者搭建后输出源码二次编写.

看到你也在看前端服务化——页面搭建工具的死与生, 可以先定位下希望做成什么样的工具, 确定哪些是需要实现的技术点, 从那篇文章上找找思路.

欢迎继续交流哈. @YHWL

winyh commented 5 years ago

看过你前天在AlloyTeam 发的文章,很受益。有2点疑问: 1.用页面挂载的方式实现即时预览,为什么会污染编辑器界面?我用的react 实现的可视化编辑,预览的时候直接把组件树还原成组件渲染。用一个渲染路由挂载一个我的渲染数据,好像没发现有污染的问题,不知道是不是技术框架的区别? 2.你的页面里的业务逻辑怎么实现的?比如组件A里一个事件钩子需要操作组件B的一个Props属性,也就是数据流的控制了。虽然可以预先设想一些可能的业务逻辑,这种业务逻辑是千变万化的,不可能完全枚举。我做的就是把事件钩子渲染出来,让用户手动编码写自己的业务逻辑 我当前也在做可视化编辑工具,定位是用编辑器生成页面级别的组件聚合成的区块,用数据描述页面,最终用浏览器生成一个React.jsx 文件下载。放在工程目录里就可以直接渲染了。希望有机会能跟你交流下

不好意思, 最近有点忙, 回复晚了.

  1. 页面挂载的主要缺点是编辑器和组件库耦合, 编辑器和组件库前端框架耦合. 样式污染问题可能会发生, 应该是小概率场景. 比如没有用 css scope, 并且给某个基础 css 选择器写了样式, 那这个 css 样式对编辑器页面也是生效的. 不过我没有实际实验这样的场景.
  2. 在我的实现中, 组件的业务逻辑是内聚的, 一个组件铺满页面宽度, 业务逻辑包含在组件内部. 在数据流方面, 并没有实现跨组件的数据流处理.

比如组件A里一个事件钩子需要操作组件B的一个Props属性, 我觉得通用组件的设计并不一定要有这样的功能, 这也不是页面搭建工具需要解决的通用问题, 这是一个具体业务问题. 组件A需要操作组件B的Props属性, 具体场景的A和B是特定业务组件, 比如优惠券组件需要去头像组件里取用户名, 那这个问题应该由优惠券组件和头像组件去约定和解决, 比如在全局对象挂属性和函数, 或通过发布订阅事件来实现等. 业务逻辑是需要具体业务场景去实现的, 我觉得不需要去枚举, 提供一个事件中心应该就差不多了, 具体组件可以订阅事件, 在事件中做逻辑处理, 由外部触发事件. 而组件是由一波开发人员开发出来的, 不会存在不了解组件有什么事件的情况. 对大部分可视化搭建工具, 逻辑部分其实是不适合通过可视化实现的. 更加简单的方式是提前定义好, 或者搭建后输出源码二次编写.

看到你也在看前端服务化——页面搭建工具的死与生, 可以先定位下希望做成什么样的工具, 确定哪些是需要实现的技术点, 从那篇文章上找找思路.

欢迎继续交流哈. @YHWL

非常感谢!我后来参考了很多,当前做的版本暂时把开组件数据流的问题交给用户二次开发。目前好像又走进了一个死胡同,我实现了根据组件的json数据树输出了 react.jsx / file.vue 文件,但是用户根据这个文件做二次编辑我没法逆向还原成 json 数据,方便将json导入编辑器平台再次可视化编辑,因为用户修改的几乎不可控。所以我目前的结论就是,用户二次编辑了基本上就不可控了。即时用户在可视化编辑器里实现二次编写,也是不可控的。不太可能实现二次编辑后再把 编辑后修改的部分再还原到可视化编辑器

miniFrank commented 4 years ago

棒,很不错的归纳和总结!

oseaweed commented 4 years ago

您好 我想问下这套框架是需要运行在linux系统上吗 目前我在windows上运行报错比较多

CntChen commented 4 years ago

@JoyZ1122 我没有在 windows 跑过, 在 mac 上是 OK 的. 可能一些 npm 的包没有兼容, 或终端问题, 或 docker 问题, 这些问题可以看下具体 case, 查阅文档解决.

raozerui commented 4 years ago

您好,想问下这样通过可视化搭建出来的项目,能支持导入IDE进行二次开发吗?(我指的是通过代码开发实现更细粒度的定制化)

CntChen commented 4 years ago

可以, 可视化编辑这里只做一件事情: 修改页面的组件列表和传给组件的数据. 比如: config/components

可以拿到搭建后的项目的源码, 自行进行修改; 不过这种修改可能就不是很深度, "魔改"有一些限制. @raozerui

axlyb commented 4 years ago

@GangRock 好问题.

  1. 组件库是可以公用一个组件库的. 但是不同的业务页面需要多个模板, 抽出组件库后会维护稍微复杂一点. pipeline 最初就是组件库和页面模板分离的, 页面模板里面放组件列表, 没有组件源码. 公用组件库的好处是组件库升级, 所有页面模板都用到最新的组件库. 不好的点在于, 组件库升级后, 一些页面模板引用的组件可能还是旧的, 就无法再次编辑了.
  2. 编辑器已经是和前端框架无关了, 也是用 vue 开发的. 为了实现 react 的 SSR 依赖了 React, 但是不影响单纯用 vue 的场景.
  3. 页面管理功能我后续加上去哈. 不会很复杂, 添加个数据库表, 添加后台接口和前端页面.

可以, 可视化编辑这里只做一件事情: 修改页面的组件列表和传给组件的数据. 比如: config/components

可以拿到搭建后的项目的源码, 自行进行修改; 不过这种修改可能就不是很深度, "魔改"有一些限制. @raozerui

有没有可能使用现有的工具链,把导入项目自动完成config,然后在此基础上进行页面组件的操作;把现有发布产品的代码改成符合要求的模版,好像工作量也不小

ctq123 commented 3 years ago

页面预览可以用你提到的两种方式的结合体,即iframe+dom挂载的方式,通过iframe来隔离框架样式上的问题,用postMessage来通信就好了,用后台实时渲染还是太占资源了

之前也弄过一版,但是只能处理纯静态的页面,最终还是倒在动态数据交互上😂

输出源码的那种预览不太好解决,比如https://github.com/ctq123/idou