看 java 味有感
假如前端有如下页面组件 a 和 b ,a 和 b 中有一部分并集的功能,比如 card 的边框,标题什么的
我一般会拆成 BaseCard ,ACard ,BCard 三个组件来写,包括 ts 也是,interface BaseCardProps ,然后被另外两个组件继承。我自认为写到还算优雅,组件分拆出来每个文件代码量一般控制在 100 行内,顶多 300 行出一点。
行数超 300 的话,后续有时间整理代码我一般会按不同功能细化继续拆分出组件。看到有人说 javaer 写点简单功能就先写十几个文件然后到处继承,每个类代码很少,难道我一直以来坚持的写法是错误的吗,all-in-one 全堆一起才是正确写法?
1
hwdq0012 29 天前
好代码是重构的,一般按经验设计就好,不用过度设计,按需要重构即可, 主干设计抓好,git flow 抓好,可快速重构,先做一个垃圾出来, 况且 mvvm 能垃圾到哪去( react 是 mvvm 还是 mvc 忘记了
|
![]() |
2
crysislinux 29 天前 via Android
我倾向于共享逻辑而不是继承组件。
|
3
Uncertainty 29 天前
写 react 天天被 上面 diss ,哎
|
4
herm2s 29 天前
以偏概全是最不可取的,你说的那种十几个文件到处继承的写法,只有时间太多的人才会那么干,都是干开发的心里清楚,自己写那点垃圾代码还没点数吗
|
![]() |
5
kxg3030 29 天前
曾几何时 写代码前 我会考虑目录结构 代码分层 各种设计模式也算用的很溜 但现在回过头去看 又有什么实际的意义呢(仅自己的看法) 熵增是避免不了的
代码规范 可读性那已经是很久以前的事情了 现在我只想一把梭 看到结果 |
6
zhengfan2016 OP @crysislinux 纯逻辑共享一般用 hook ,这个主要是样式和 dom 结构上的共享
|
![]() |
7
serco 29 天前 ![]() 为啥你会觉得除了十几个文件继承,就只剩下全堆在一起的写法了。
继承现在不都丢得差不多了吗,都是 mixin composition |
8
zhengfan2016 OP @hwdq0012 react 和 vue 是 mvvm ,好像只有 thinkphp 等那些传统后端渲染才是 mvc
|
![]() |
9
InkStone 29 天前
如果没有哪个地方需要以 BaseCard 作为通用去访问这两个组件,那不建议以 is-a 的语义做抽象。如果有的话,也优先使用 interface (我不熟悉 ts 的 interface 语义,不知道是不是跟 Java 一样),interface 用不了再考虑继承。
|
![]() |
10
wangtian2020 29 天前 ![]() 我不拆,你越是想把耦合的东西拆开就越发现自己在浪费时间。页面逻辑本来就是耦合的,代码为什么要解耦,根本解不出来,左手倒右手的解耦没意义。
|
![]() |
11
shintendo 29 天前 ![]() 感觉就是过度设计强迫症,跟 react 关系不大
|
![]() |
12
ipwx 29 天前
成熟的组件库,card 一般也没 N 个。
如果你需要 N 个 card ,不如想想你是否有这么多种风格非常不一样的 card 。能不能用参数解决 |
13
zy0829 29 天前
@Uncertainty 为啥
|
14
bler 29 天前
我的建议是有个大致的模块继承关系就行,别在基类放太多东西,就算 A,B card 有重复的定义也行,避免到时候又出现一个 C Card 但是不需要 base card 中的某一个属性。我之前写代码就是这样,写的太细了,考虑的太多了,尤其是项目从 0 开始的时候,有一个大致的继承关系就行,别考虑太细,扩充容易,但是拆分功能难,人无法考虑东西特别完整,留着扩充的接口,写重复代码无所谓,以完成任务为主,后续项目功能完善了,再考虑提取公共部分的内容
|
15
136475688 29 天前
组合优于继承。
|
![]() |
16
RRRSSS 29 天前
关键是拆完之后,如果之后想要添加个 props ,还要全盘考虑兼容已经用了这个组件的页面。
我的意思是,如果是业务页面,怎么简单怎么来吧。 业务逻辑用 hook 复用 样式组件基本现在都有组件库吧,再封装一些针对业务的组件(Title 、Card 什么的) |
![]() |
17
crysislinux 29 天前 via Android
@zhengfan2016 共享组件结构我倾向于拆开搞几个组件来组合,共性不是很大我倾向于各搞各的。
|
![]() |
19
wu67 29 天前
个人经验, 相似界面的业务组件, 不写成一个. 相似的数据逻辑, 写成函数.
接手过最离谱的一次💩山, 一个弹窗表单组件 7 个页面用到, 改一个地方, 查 7 个页面有没有改错... |
20
paopjian 29 天前
基础组件可以拆细点, 但是定了型最好就别改了
我是宁愿复制一份给新需求, 也不敢去再改已上线的功能, 越想着适用各种场景, 未来要细调的地方越多. 麻烦的一点就是如果要统一加什么功能还得一个个去改. |
21
zhengfan2016 OP @ipwx 一般单纯能用 className 解决的,肯定不会分拆组件的。就算 tailwindcss 超长,也有 cva 这些好用的 tailwindcss 复用工具,像我需要分拆的都是属于两个组件 dom 层级不相同的组件。
|
![]() |
22
NerbraskaGuy 29 天前
组件癖吧,之前遇到的一个老项目,里面公用组件就快百来个,有的点进去看还就十几行代码,要说删掉吧,组件之间互相嵌套还贼复杂。
|
23
kneo 29 天前
好像还是 java 味儿,没看出 react 味儿。
|
![]() |
24
jqtmviyu 29 天前 ![]() 不超过三处地方复用, 我宁愿 ctrl+c ctrl+v.
设计赶不上需求变化. 特别是那种某个日期后页面展示发生变化, 但还得兼容旧的数据, 我直接 cv, 复用是不可能复用的. |
25
chenliangngng 29 天前
永远不要主动写继承,除非你接手的是写前端的 javaer[doge]
|
![]() |
26
SayHelloHi 29 天前
复制 + 粘贴 上线能跑就行 😁
|
27
DICK23 29 天前
react 的代码风格就不适合继承写法
|
28
jiuhuicinv 29 天前
能出活就行了,怎么实现的不重要
|
29
jamesjammy061 29 天前
我一般是写一起,大了再拆出来。或者预期一开始就能预料到是分开写的,我也会先写一起,写的一定程度再拆
|
![]() |
30
angrylid 29 天前 ![]() 我难道穿越了?
React 前几年的复用方式是 Mixins 和 HOC ,近些年是 Hooks ,到底哪个世界线的 React 依赖继承来复用。 |
31
ty29022 29 天前 via iPhone
Sonnet3.7 幼稚的碳基生物
|
![]() |
32
sjhhjx0122 29 天前
拆成互不关联的功能还行,我觉得最完美的是底层单一功能或者只有样式的 Headless 组件,中间一层基于 Headless 组合的功能组件,最后写一个大而且全的脏业务组件
|
![]() |
33
otakustay 29 天前
真正的 react 难道不是<BaseCard customize={<ACard />}>这样吗,你这 extends 的不够 react
|
![]() |
34
ragnaroks 29 天前
过度设计,如果时间充裕倒也不是坏事,但是往往最缺少的就是时间
|
![]() |
35
leokun 29 天前
我是把不一样的地方用 children 或者 props 传进去,应该是最直接的方法,而且也没那么烂
|
37
qingyingwan 29 天前
看起来感觉是工作经验比较少的前端。我当年 react 一两年经验的时候也经常纠结这种代码细节。现在做后端了,也遇到过这种纠结细节的,各种规则一大堆,代码 pr 要一周。结果核心的服务性能,延迟,稳定性,可观察性,架构设计都是依托。
|
![]() |
38
tonytonychopper 29 天前
我一般会写一个 Card ,视情况在 Card 提供 props 做差异化
|
![]() |
39
gouflv 29 天前 via iPhone
前端组件早就不是 oop 的思维了
|
![]() |
40
twofox 29 天前
我实在是太想吐槽公司的项目了。我说不上它到底是 vue 味还是 react 味,但可以肯定一股子屎味
前端用 vben admin 2.x 当脚手架 一个 vue 项目,学 react 封装了一大堆 hook 。配合 vue 稀烂的 ts 支持,用的实在是太难受了 |
41
sakura1988 29 天前
先证明 A 和 B 的并集真的是公共的,再来复用。
很多时候只是目前看起来一样罢了,相似而不同、皮像肉不像。后续加一点变化,A 和 B 的并集就跟着变小,然后这个复用就作废,并且直接逆变换为屎山。最终结果就是两个完全无关的东西被缝合成一个弗兰肯斯坦。 |
42
superedlimited 29 天前 via iPhone
|
![]() |
43
bojue 29 天前
@crysislinux #17 职责单一原则有时候更清晰一点,可复用组件只要不断迭代 case 迟早都是 s 山
|
44
zhibisora 29 天前
别拆了, 如果本来就是耦合 UI 或者单个页面的写一起算了, 单文件 600 行还是能读的, 逻辑可读性还能更高, 代码也能简化. 这几天天天看有人说用 claude 写 4000 行的单个文件:) 等以后 ai 能改准了, 没必要考虑拆分, 等要复用时再拆好了
|
![]() |
45
twig 29 天前
我就爱这么写。将来 refactor 的时候,找到那一个地方,嗖一改,就得了。挺省事儿啊。
|
![]() |
46
bruceczk 28 天前
你要是每次遇到重合都抽一个新的组件确实是有点烦人了,毕竟嵌套层数太多也影响效率的。
|
47
xzh654321 28 天前
组合优于继承
|
48
mxT52CRuqR6o5 28 天前 via Android
我个人的经验是:宁可复用不足,也不要过度抽象,复制粘贴也没啥
提前优化是万恶之源 |
49
mxT52CRuqR6o5 28 天前 via Android
设计师不参与的 UI 组件抽象其实没啥意义,因为没有沉淀成设计规范
|
![]() |
50
keithwhisper 28 天前
首先是一点函数式的味道都没有...
然后这种是无效抽象, 只是现阶段代码相似罢了... 复用代码最好是从逻辑的角度去考虑, 而不是代码块是不是可以合并 |
51
ochatokori 28 天前
我写 vue 也差不多这样,像一个上传接口有多种上传样式,我会把上传部分写成 base ,每个样式都写成一个组件,上传逻辑继承这个 base
|
![]() |
52
kongcc 27 天前
看是复制粘贴的成本是否大于拆分的成本。拆分完又不复用,不是自己找麻烦吗
|