• home > webfront > ECMAS > vue >

    前端组件化:vue组件设计思想与遵从原则

    Author:zhoulujun Date:

    从页面元素的可复用性角度考虑,我们将将组件按类型分为公众组件、容器组件和视图组件。模块(Module)通常强调的是职责(分离、内聚),组件是可复用模块和相关依赖的封装。组件拆分目的:复用与隔离

    组件化的工作方式信奉独立、完整、自由组合。目标就是尽可能把设计与开发中的元素独立化,使它具备完整的局部功能,通过自由组合来构成整个产品

    从页面元素的可复用性角度考虑,我们将将组件按类型分为公众组件、容器组件和视图组件。

    模块(Module)通常强调的是职责(分离、内聚),组件是可复用模块和相关依赖的封装。

    组件可以如下定义:

    • 可复用的模块,完成既定功能

    • 有明确的接口规定

    • 有上下文依赖、外部依赖资源的定义

    • 可以独立发布

    为什么要组件化

    1. 组件化是对实现的分层,是更有效地代码组合方式

    2. 组件化是对资源的重组和优化,从而使项目资源管理更合理

    3. 组件化有利于单元测试

    4. 组件化对重构较友好

    Vue组件库包含组件(Component)、指令(Directive)和过滤器(Filter)三种类型的存在。

    组件多层嵌套时,应该把Modal放在根组件里,然后在子组件里通过事件触发。在具体应用里,应该这么用,这符合Vue提倡的“状态驱动”。

    组件化设计流程

    组件设计的一些理念

    在设计组件的时候需要考虑到很多方面,以便它们可以很好的复用,组合,分离和低耦合

    以下原则尽可能使用

    • 单一职责原则

      • 组件里的每个模块,分别该承担某一个功能

      • 多个组件 / 模块协同完成一件事,而不是一个组件替其他组件完成本该它自己完成的事情

    • 开放封闭原则

      • 属性配置等 API 对外开放;组件内部 dom 及状态的更改、对外封闭

    • 高内聚、低耦合

      • 组件内部通过 callback 方式直接调用,组件与组件之间通过发布订阅的模式通信

    • API 尽量和已知概念保持一致

      • API 命名:比如 聚焦 常用命名是 focusable 而不是 canFocus 等自己臆想的名字、还有如 onDeselect 等规范名字。

      • API 的功能要单一并表意:比如 active 表示活动状态、但不能代替表示 selected 选中状态。

    • 追求短小精悍

    • 避免太多参数

    • 缩小信赖范围和向稳定方向信赖

    • 适用SPOT法则 (Single Point Of Truth,就是尽量不要重复代码,出自《The Art of Unix Programming》)

    • 无副作用

    • 引用透明

    • 避免暴露组件内部实现

    • 避免直接操作DOM

    • 适用好莱坞法则 (好莱坞法则: Don’t call us, we’ll call you, 又称IoC, Inversion of control, 控制反转)

    • 入口处检查参数的有效性,出口处检查返回的正确性

    • 充分隔离变化的部分

    • 组件和数据分享,信赖一致性的数据结构


    以下 8项是我认为值得去注意的

    • 层次结构和 UML 类图

    • 扁平化、面向数据的 state/props

    • 更加纯粹的 State 变化

    • 低耦合

    • 辅助代码分离

    • 提炼精华

    • 及时模块化

    • 集中/统一的状态管理

    单一职责

    组件拆分目的复用与隔离

    • 隔离的类型,组件业务必然很重,此时虽然要保证组件尽可能简单,

    • 复用类型的,通用性更强,所以功能越单一,使用起来就越方便。

    我们知道 react 有一个概念:container/component,

    即 component 只是渲染组件,而 container 才是产生业务的组件,我们 Vue 也可以依照这个理念进行设计。

    即把数据处理等带有副作用的工作放在父组件中,而子组件只进行展示或操作,通过事件的方式让父组件进行处理

    保证逻辑归一,后续维护也更为方便。或者使用 slot 等类似高阶组件的方式来简化当前组件的内容。

    无副作用/引用透明

    和纯函数类似,设计的一个组件不应该对父组件产生副作用,从而达到引用透明(引用多次不影响结果)。

    数据操作前必须进行复制。比如需要添加额外的键值,或者需要对数组类型的数据进行操作,会对原始数据产生影响

    注:引用类型的 props 千万不要直接修改对象,虽然能够达到传递数据的目的,但会产生副作用,如果有其他地方用到该数据,可能产生未知的影响。

    组件划分颗粒度

    组件拆分出来之后,拆成几层或者是拆成几块,影响文件的数量。如果层级比较多,各种 props 传递,事件传递,维护成本比较高。

    保证逻辑处理集中在一个组件,维护也比较方便。

    新功能下添加新属性/新文件

    对于通用类型组件,我们要求它尽可能的短小精悍,调用起来更为简单,所以不能设计太多的参数。基础组件库不能符合这个要求,

    主要是因为基础组件库需要尽可能增加普适性,不会因为没有某个常用的属性,导致该组件需要复制一份重写,再加上日积月累的 pull request,

    属性和参数必然会越来越多。而我们在业务中使用,完全不需要这么多的配置,如果有重大差别,重新复制一份,对于后续的维护反而更方便。

    所以是否新增加属性还是拷贝一份,是根据后续该组件是否会产生比较大的发展方向差异来决定的。

    Vue 组件之间的交互设计

    Vue 组件与 React 组件有比较大的区别,模板的设计更偏向于 HTML,所以要实现类似 react 的高阶组件的需求通常比较少,

    而高阶组件集成度过高,对于业务来说,当业务越来越复杂,组件内部逻辑将拆分困难,未必是件好事,所以我们只讨论普通的组件设计。

    组件设计是考虑组件通讯方式,主要分为以下几个方面:数据流转(向下传值,向上传值),伪双向绑定,方法调用

    简化与抽离的其他实现

    使用插件或者 mixins 实现


    抄袭源头:

    如何去设计一个组件封装_前端组件化设计思路 www.fly63.com/article/detial/996

    漫谈Vue组件库开发 https://jdc.jd.com/archives/212167

    [译] 前端组件设计原则 https://juejin.im/post/5c49cff56fb9a049bd42a90f

    前端工程——基础篇 https://github.com/fouber/blog/issues/10

    前端组件设计杂谈 warmhug.github.io/2018/09/09/components-design-experience.html

    化整为零!关于组件化设计升级的一些思考 https://www.imspm.com/article/1499653624086?p=1&m=0


    转载本站文章《前端组件化:vue组件设计思想与遵从原则》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue/8526.html