编写Web组件的6个建议

“组件化”是近几年web前端开发的趋势,关于如何设计出好的组件,本文总结了6点经验,希望对读者有所帮助。

减少依赖

尽量不要和其它组件共享变量,保持原子性,依赖过多会影响组件的可复用性和稳定性。

尤其不要从路由中取参数(导航栏等本身就依赖路由的组件除外),例如:

1
2
3
...
this.type = $stats.params.type
...

因为这样编写的组件相当于和路由绑定了,一旦路由发生变化,或者在其它页面复用时就会发生问题。

正确的做法应该是声明为组件属性,值由父组件传过来。

避免扰乱文档流

组件外层元素尽量不要使用绝对定位、浮动这类打破静态文档流布局的样式,这些样式会使得其它组件布局发生难以预料的变化。

单一职责

一个组件尽量只处理一个逻辑,拥有一种状态。

举个常见的例子,比如我们在开发中经常使用的API接口,如果要开发组件,实现展现详情、编辑和新增的操作,该怎么设计?

详情页面

编辑页面

按照业务来划分,这些都是对与某个API进行的操作,是不是一个组件就可以搞定?

这么做似乎做到了“高内聚”,但是我们仔细一想便会发现,展现状态和编辑、新增时的状态明显不一样的,一个是不可编辑、一个是可编辑,更重要的是在这两种状态下结构和样式都发生了较大变化。所以这样做在逻辑变得复杂时(比如添加了各种逻辑校验、联动),容易相互影响,难以维护。

如果按照状态来分是不是要分别写成3个组件?

可以这么写,但是似乎没有必要,因为编辑状态和新增状态的逻辑基本相同,只是编辑状态下需要回填数据而已。

所以比较好的方式是展现详情写成一个组件,编辑和新增写成一个组件。

根组件尽量简单

单页应用通常会有一个根组件,它内置路由的容器层,其它组件都通过路由填充在里面。

有的开发者可能会想到把一些公用组件放到根组件上,比如说侧边栏、菜单栏。

1
2
3
4
5
6
App
|--public-component-1
|--public-component-2
|--router-view
|--page-1
|--page-2

但是这样做可维护性是个问题,如果碰到个别页面不需要显示这些公用组件就不得不在组件内部进行单独判断,需要修改原来的逻辑。

更好的方式是在根组件的路由容器层中重新创建一个路由容器层,用来放置这些公用组件。这样可以将需要使用公用组件的页面挂载在该容器层,不需要使用公用组件的页面还是可以正常挂在根组件上。

1
2
3
4
5
6
7
8
9
App
|--router-view
|--page-3
|--main
|--public-component-1
|--public-component-2
|--router-view
|--page-1
|--page-2

避免垃圾元素、变量

1
2
3
4
5
6
7
8
this.id = $state.params.id
...
http.get('/xxx/' + $state.params.id)
// 建议使用之前声明的变量进行操作
http.get('/xxx/' + this.id)
...

避免污染全局样式,不要使用style

css没有作用域,但是可以通过选择器的方式来实现。

例如vue组件就是通过随机属性。其它组件开发也可以使用简单的方式,比如组件的根元素上绑定一个唯一命名的样式,然后组件内部样式都嵌套在根组件之下。大多数情况(有一定的组件命名规范或者组件名不重复)下也可以实现作用于隔离。这样做的好处就是组件之间不会因为样式重名而相互影响。

至于不要使用style属性,应该是一个比较基础而又常见的问题。因为style的权重太高,会导致组件样式无法重载修改。大大降低组件的灵活性。

亚里士朱德 wechat
更多WEB技术分享请订阅微信公众号“WEB学习社”