为什么我反对在 ui 组件库之上,再作对 template 进行 for 循环遍历 json 的封装?

2020-06-08 10:27:13 +08:00
 revalue
看到隔壁贴,/t/679490 ,这个老哥最终成品方向还不确定,我也不是针对这个老哥的模式。我把其一个可能的方向简化的话就类似于这个链接 https://www.cnblogs.com/wisewrong/p/9052467.html 。(代码超级简单)

这个原理也很简单,就是在 vue template 上 for 遍历这个 json,通过 if else 得出最后的 vue dom,就是这样封装。其实这个循环加封装就损失掉了 template 的可拓展性,应对复杂的场景,你必须用 hack 的方式设立并传个 slot 进去这个组件把损失掉的 template 拓展性给补回来。然后你这种 hack 又要加字段说明。像这样,每个人往上面补一刀,之后这个模块基本上就废了。

除非你这个 json 设计,可迁移和可拓展性很强,比如你 json 还有别的用途,能拓展出新的配套功能配套设施。否则我觉得这是“脱裤子放屁”,这种封装只是把数据换了一种形式来表达,从 html 转为同等的 json,代码量几乎没减少,只能说在个别人看来,js object 比一大段 html 代码要美观一点。我组里已经有很多同学做成这个样子作为封装来邀功,“百花齐放”,封装后调用接口不一,我觉得用起来太难受了。

我不是说反对 json Schema 。而是反对根据 json Schema 来在 template 上 for 循环遍历然后 if else 。其他的比如根据 json 代码生成 template 代码,我是比较看好的。

PS:我想了下为什么封装那么难,以至于我更提倡代码生成器,是因为 vue 的 2.x 版本没有提供对 template 的“业务逻辑”的封装。受 react hooks 影响,在最近两年其他框架新版本开始有对业务逻辑的封装。而对比来看,像 vue 如果去封装“ui 组件库”,问题不是很大的。
3824 次点击
所在节点    Vue.js
26 条回复
revalue
2020-06-09 09:46:26 +08:00
首先“需求常变更调整”是另外一个问题,是侧面影响这个问题的因素。

如果把 1000 行 template 用 json Schema 来描述,就会变好了吗?除非你把后端发过来的 json 直接拿来用。json Schema 来描述,你的 template 就要考虑是否循环遍历 json 然后渲染了,只是最多把一些默认的配置封进去而已,如果这些默认设置不满意,就需要加组件参数去改。我说的就是这种参数特别难维护。
wly19960911
2020-06-09 09:55:39 +08:00
@revalue 这种参数很难维护吗?无非就是根据计算属性来处理相关的多个参数合并操作,而且我用的数据结构类似 echarts 的 series,不同的 type 不同的选择项,加上完全的 typescript 注释和工厂类创建。维护业务组件的正常操作而已。不满意继续加新的 type,老的组件不动,开发新的组件来逐步替换老组件

而且新的需求上来了,你也要去改老组件啊...这种遍历循环 json 的组件真的没什么难做的,难做的是那些带 if 逻辑的 json schema,我也没兴趣做,因为完全没必要,我这里效果太差了。
taowen
2020-06-09 13:46:16 +08:00
一个解决方案本身并没有对错和好坏,要看这个解决方案是解决什么问题的。我尝试列举三个问题:

* jsx / tsx 等方案的编程反馈周期慢,一个界面的修改,从改源代码到看到效果需要好几秒钟(如果 webpack 等优化不好的话)。
* 最终用户需要能够自定义自己的界面,比如店铺要装修,报表需要自定义的仪表盘。
* CRUD 写得太烦躁了,每个都差不多。但是每个又有不同。

从这三个问题出发,都有动机自己在现有的前端技术上架一层。

* 拿 JSON/XML 等方式定义一个自己的模板语言,自己写一个解释器,然后支持拖拽。所见即所得的 GUI Designer,解决了反馈周期慢的问题。
* 给用户一个店铺装修器,生成的描述文件存数据库。渲染的时候取出来,动态执行。
* CRUD 就不用说了。解释器的方案就是动态代码生成。静态代码生成是另外一条路。仅仅是生成的话,静态动态区别不大。难点在于 20%不同的逻辑,怎么指定。静态的方案要比动态的方案更好做一些。

每个不同的问题,对于最终这个方案好还是坏的定义都不同。每个问题都有自己细微的难点,比如 Gui Designer 怎么表达复杂的响应式排版,CRUD 怎么表达差异的逻辑部分等。做出一个 60 分的解决方案,可能带来的收益,还不足以支付切换解决方案带来的成本。
xingyuc
2020-06-09 14:29:07 +08:00
@jrtzxh020 上百个页面弹窗里面的输入框,cell……想想就可怕
xingyuc
2020-06-09 14:35:55 +08:00
@taowen 网易博客、QQ 空间的效果么
wisetc
2020-06-09 19:44:40 +08:00
还是 json 大法好,这种我用过的,适合大表单,好处是利于测试,以及可以赋初值。看下面的定义就晓得了,属性超级多。

```ts
enum Widget {
div,
radio,
radioGroup,
select,
date
}

interface Option {
label: string;
value: string;
}

interface Field {
label: string;
hideLabel?: boolean;
id: string;
type: Function;
hidden: boolean;
labelAsSuffix?: boolean;
defaultValue?: any;
belongsTo?: string;
widget?: Widget;
required?: boolean;
options?: Option[];
fetchMethod?: () => Promise<any>;
delayFetchMethod?: () => Promise<any>;
suffixText?: String;
postMethod?(val: any): any;
fieldSet?: Field[];
close?: boolean;
rest?: object;
}
```

随手定义的分享出来,不过自己写的,别人未必能看懂。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/679611

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX