问题

吾辈写了一个简单的示例代码说明目前遇到的困境(虽然是 react 不过框架之间原理是相通的),其实就是组件内的代码在某个权限下才会执行,但是又依赖于组件内的一些状态,如何将这些代码分割到不同的地方(例如不同的文件)便于之后的维护。

7e69d69a9157f9880390cfb28f9a12eb.png

b96ed8f9915d324a238c66ea6f2cc520.png

8e51e2ceb7bf034de3b0a01f796172e7.png

这个例子里面有两种角色,normal/vip,普通用户可以试用 vip 的功能,vip 角色不能出现普通用户的试用功能,从功能上看很好实现,但问题在于如何将这些互相耦合的代码分割,理想情况是在进入页面初始化时就确定要加载的 state/methods 了。

2535ac9cc61e98e49aacc7417570e845.png

虽然这里只有两种角色,但吾辈丝毫不怀疑真实场景会有更多,当然真实场景是角色下面还有权限,某些东西是角色所属的(只要是这个角色就一定有),而有些则是权限所属(必须拥有某个权限)

那么,有什么优雅的方式将这种与权限相关但相互存在关联的代码(state/method)分离么?

具体代码在:https://github.com/rxliuli/admin-man-sys/blob/f97534e94e/src/pages/index/permission/REditable.tsxopen in new window


下面使用类的形式实现了代码分割,但似乎并没有更加简单。。。

a825c2280b163c296a4979bd9606828d.png

具体代码在:https://github.com/rxliuli/admin-man-sys/blob/master/src/pages/index/permission/REditableWrapper.tsxopen in new window

讨论

  • Meathill

    1. 大体上,你只需要考虑界面上有区分即可。代码拆分价值不大,毕竟压缩后最多十几 K,对加载速度和响应速度的影响都微乎其微,但是要花时间设计代码结构。
    2. 非得要做,可以考虑 webpack lazyload 功能,分拆模块为不同文件。
  • 我: 一个主要的渴求是将这些代码按照权限分割出去,便于之后的维护,代码大小本质上不存在什么问题(倒不如说分割之后再打包反而更大)

  • Meathill: 按照权限分割代码未必有利日后的维护。可以好好读一下《重构》和《设计模式》。

  • 我: 这种诉求并非完全来源于前端,而是来自于经理(后端)的想法。。。

    经理:我理解应该是根据图片是什么类型确定进哪个类型的 “实现 “, 这里是什么设计?为什么感觉糊里糊涂的 经理:前端把公共代码抽象出来不行吗?时间不够也应该按这个思路做,稍微有复制的代码,至少设计没问题 经理:列表页就知道是什么类型的图片不是吗?为什么这里不能决定进哪个实现? 我:现在是从官网跳转时加的 query 参数 bizType 确定类型,然后基于此拿到对应的权限(permission)列表,然后根据是否有权限控制元素的显示隐藏,本身逻辑代码还是一起的 经理:这个不是个很典型的面向对象的多态吗?是什么原因不能抽象和做两个实现? 我:那是后端万物皆类的情况,前端组件化场景下要考虑的是组件分割之后,代码复用、通信带来的麻烦是否过高 经理:这是做到什么程度的问题,目标是流程复用,实现独立,新增一个类型不能漏实现。就像后台那个答题新增一种题型还要记着去改统计那里,太蠢了

    最终实在不行我们或许只能采用 mixin 这种不是很好的解决方案了。。

  • Meathill: 其实吧,HTML/CSS 的崛起已经证明了 “面向对象的多态” 在 UI 开发方面天生不足。但是这一点展开讲太复杂。推荐你和你的经理看看尤雨溪(Vue 的作者)前阵子的演讲《State of Components》,了解一下 React Hooks 和 Vue Composition API,再来看这个问题,可能看法就变了。

  • 我: 最终我找到了一个用【类】的形式去分割操作逻辑的方法,不过感觉文件真的多太多了,而且还要想办法在 vue 里重写。。。(参考上面的补充)

  • 我: 好吧,现在吾辈已然实用了 react hooks,确信 hooks 是一种更好的解决方案!

解决思路

  • mixin 混入
  • 使用高阶组件
  • 使用 hooks 封装逻辑

解决方案

经过 hooks 的实践,吾辈发现 hooks 实在太适合封装 UI 和逻辑代码了。 因为 hooks 几乎能做到所有组件能做到的事情,同时没有组件那么,事实上,很久以来 react 都允许写一个函数返回 UI,但这仅适用于无状态组件,对于有状态的组件,之前只能使用类组件。但现在 hooks 却极大增强了函数的能力,甚至为函数开了后门 -- 所有 use 开头的函数均被认为是自定义 hooks。