组件的划分
laizimo opened this issue · 2 comments
前言
本篇主要来聊一聊组件的划分的那些事。现在的前端开发,都是围绕着组件展开的。我们逐渐意识到,理解组件化的含义,清楚组件划分的规则至关重要。如何做到组件与组件之间的耦合度尽量的小,如何完成子组件和父组件的划分,或许,是我们开发一个优秀的系统前,需要去认真思考的问题。如果你喜欢我的文章,欢迎评论,欢迎Star~github博客
正文
本篇文章主要使用的数据驱动框架是vue,所以后续的组件划分中,也主要是围绕着vue组件展开的。或许,你会有疑问,React和Vue的组件性质不应该是一样的吗?是的,可以说两者开发出来的组件都非常的相似,但是,还是有些细微的差别。
比方说,无状态组件,大家都知道React中的无状态组件,只有props这个外部给予的属性。但是,在Vue中,你会发现似乎也有类似的组件,只提供props不就可以了么。但是,它仍然是具备data的。所以,归根结底,它只是不去使用状态,而不是没有状态。
扯了这些东西,我们回到正题——组件的划分。
这里需要我们去思考一个问题——组件以何为分?
首先,我们以写代码这件事来举个例子。我们说好的代码里面,函数必须只满足一个功能。一旦,你的函数实现的效果太过于繁杂,那么,这就意味着其他地方需要修改这个函数的部分功能时,总会来这里做修改。“牵一发而动全身”,场景越来越复杂,总有改不动的一天。
通过上面的例子,我们回过头来聊组件,划分的原则:
一个组件只做一件事,基于功能做好职责划分。
我们需要在项目开发过程中,始终履行这个原则。在项目的初期、中期还是后期,往往会出问题的是初期。为啥?
因为开发初期,往往整体的系统功能单一,展现形式单一,这也误导我们做出错误的思考。
例如:开发一个信息查询系统,前期最多的就是输入框。可能一开始的输入框形式比较单一,校验形式单一,所以我们会将它统一封装成一个text-input组件。愚蠢的是,我们会将校验的逻辑写进组件里面,因为一开始的表单只有一种校验逻辑,写进组件中可以省下很多代码。
后来,突然增加了,一个验证码输入框,需要有部分内容去显示验证码。这时,我们会思考需不需要将之前的text-input进行拆解。但是,仅仅增加了一个验证码而已,我们完全可以使用v-if指令来控制这种情况。于是,草草了事,又在text-input上添了一个props去确认是否使用验证码组件。堂而皇之,之后的短信输入框来了,我们又可以在原先的验证码的基础上,增加短信按钮。而且由于整个信息查询系统,对于输入框的使用量剧增,开始出现不同的输入框校验方式。我们又得去输入框中,进行修改。总有我们不敢改的一天,因为不同业务线,使用的输入框组件,大多都是这个,不可能每次测试都会来测一下每条业务线的逻辑。
基于上诉情况,我们回过头来思考,我们为在前期做好一件事情——单一原则的划分。
撇开上述案例不谈,我们先来看看正常情况下,我们如何来划分组件的,如图:
这里依然扯到了无状态组件(在vue中,我们可以考虑只使用props的组件)。
理解一下UI组件:即UI单元,如输入框、tab框、表格、下拉框。我们可以来看一下2017年vue的UI库发展情况:
可从图中看出,element这个vue的UI库,增长的速度非常之快,或许是国内的教程大多数使用的UI库都是element的缘故吧,iView同样在快速增长着。
移动端的UI库,同样也有Mint UI和vux。
回到之前的话题,我们可以将组件分割成一个一个的业务组件,然后业务组件可以通过UI组件和无状态组件组成。这里的无状态组件可以给个定义:只接受props,根据不同的props展现出不同的样式,并且会抛出事件来通知外部组件需要的更改。
回顾之前的案例,我们也可以进行如下的操作:
由于前期开发中对text-input这个组件塞入了太多不应该的东西。所以,我们需要一个将之前的短信、验证码、普通的输入框分成三个不同的业务组件。然后,可以使用既定的UI组件库来进行拼接。
还剩下一个容器组件:
它就相当于一个盒子,包含着各种业务组件,同时它也承接了各种数据,然后对这些数据进行分发。在组件的划分中容器组件扮演着至关重要的角色。
总结
我们将组件划分成三种组件:容器组件、无状态组件和UI组件。这样,我们就可以按照既定的原则去处理组件。同时,在拿到产品的原型稿时,我们也需要去认真地思考这个问题。我们可以将页面分成几个模块。
需要明白的是:
- 越小的单元,state就越需要单一
- 不要在UI组件和无状态组件中进行数据的请求,应该将之放入容器组件中
- 单向原则,子组件不应该影响父组件
最后,希望你能够在实践中去进行运用。
如果你对我写的有疑问,可以评论,如我写的有错误,欢迎指正。你喜欢我的博客,请给我关注Star~呦github博客
欢迎订阅微信公众号
issue竟然可以这么用。。。