美文网首页
如何写好一个组件

如何写好一个组件

作者: JackfengGG | 来源:发表于2021-03-05 10:32 被阅读0次

    前言
    自从三大框架以来,现在前端开发都是以面向组件开发为主
    相信同学开发的组件连起来可以绕地球一圈
    当我们拿到一个页面(如下),脑子里快速把页面划分了几块,然后迅速进行coding

    mice.jpg

    问题
    那么问题来了。
    组件构成是什么?
    划分的组件到底是什么粒度?
    划分的组件怎么分类?
    划分的组件如何更好的复用?
    让我们一个个回答吧

    组件的构成

    一个完整的具备功能的 UI 组件的构成,有结构(structure)、表现(presentation)和行为(behavior)这三个方面。

    结构

    • 视觉结构(内容结构,布局样式)✖
    • 内容结构(html视图结构描述)▲

    表现

    • 主题风格/皮肤(UX审美想法) ●

    行为

    • 交互逻辑(交互想法) ✖
    • 业务逻辑(实际业务规则)●

    ● 经常变动 ▲ 容易变动 ✖ 不怎么变动


    对于不怎么变动的东西,就要考虑问题
    1.在某些场景可否把视图抽离出来,让页面复用,比如Mice下的[新增页面]和[编辑页面]
    2.某些组件是否可以单独抽离创建一个项目,比如租车,用车,包车。
    3.某些小而好用的组件可否抽离出来放入hl-ui里面,让更多的同学去用。
    ...

    对于经常变动的东西
    1.在某些场景可否把文字都抽离出来,达到快速上线的目的。
    2.可否把一些功能做成配置项,让业务人员去配置。
    3.是否要把这一块功能让外部去实现,给予更大的空间。
    ...

    划分的组件到底是什么粒度? 原子设计原则

    按照原子设计原则,我们组件应分为五种

    原子组件

    原子组价是组成所有组件的最基础的元素,具有不可再分特性。
    如上图<span style="color:red">红色区域</span>。一个按钮,一个文案,一个线,一个icon。
    通常是游览器提供或者框架库内提供类似Button, Input(虽然有些是div模拟等实现,有些甚至很花哨,但组件设计语言上,不管什么样的Button都属于原子组件)

    分子组件

    分组组件是几个原子组件组成的组件。例:Label + Input 或者 Tabs。具有一定可操作性。
    如上图<span style="color:blue">蓝色框区域</span>。

    生物组件

    生物组件由原子组件和分子组件组成,更专注于某一独立模块区域功能。例:列表, 日期选择,Dialog,等hl-ui里大部分组件。
    如上图<span style="color:green">绿色框区域</span>。

    模板组件

    模板组件由原子组件,分子组件,生物组件组成,更加完整的一块功能,如页面的基本信息模块,添加服务模块。
    如上图<span style="color:rgba(232,139,0,1)">黄色区域</span>。

    页面组件

    页面组件是由以上所有组件完成。非常完成的一大块业务逻辑。

    来自于atomicdesign

    Info
    那我们知道这个有什么用呢?
    当我决定哪个组件是什么类型后,就应该知道属于他的“位置”,对这个组件加以“约束”,有个较为清晰的组件类型划分界限。

    组件分类

    按功能性划分

    atom1.jpg

    按业务组件与UI组件划分

    业务组件和业务强绑定的组件
    UI组件称为基础组件,更多的被复用,不耦合任何业务功能。一般是由Hl-ui等框架提供.

    按纯组件与非纯组件划分

    纯组件更像纯函数,指的是当Props,state相同,则组件展示完全相同,不依赖任何接口/外部变量。
    在React下,可用Component 和 PureComponent区分。

    按布局组件和内容组件

    布局组件,如Grid, Layout,栅格化等
    内容组件则是实实在在看的见得组件如 Input, Label等

    按是否是纯展示组件

    分纯展示的组件和有操作的组件

    tips
    如果是纯展示组件
    在React下面就可以考虑用 PureComponent。
    在Vue下面就可以用Object.freeze 和 deepFreeze来减少不必要的Observer

    deepFreeze实现如下

    // 深冻结函数.
    function deepFreeze(obj) {
    
      // 取回定义在obj上的属性名
      var propNames = Object.getOwnPropertyNames(obj);
    
      // 在冻结自身之前冻结属性
      propNames.forEach(function(name) {
        var prop = obj[name];
    
        // 如果prop是个对象,冻结它
        if (typeof prop == 'object' && prop !== null)
          deepFreeze(prop);
      });
    
      // 冻结自身(no-op if already frozen)
      return Object.freeze(obj);
    }
    

    组件如何更好的复用?

    单一原则

    一个组件应该做一件事情。
    说烂的高内聚,低耦合。
    但往往我们在“合适”之间做很多取舍。
    这个“取舍”不仅在当下,也在项目的变化中不断的“再取舍”

    KISS原则 (Keep it Simple Stupid)

    Essentially, if the component needs no state - use stateless functions.
    如果组件没有状态,则使用无状态组件

    Perf matters: Stateless fns > ES6 class components > React.createClass()
    性能上比较: 无状态函数 > 有状态函数 > class组件

    Don’t pass any more props than required {...this.props} only if the list is big -- if not pass individual props.
    最小化 props(接口). 不要传递超过要求的 props

    Too much flows of control (If-else variations) inside the component is usually a red-flag. This most likely means - need to split up the component or create a separate variation.
    如果组件内部存在较多条件控制流, 则需要对组件进行抽取

    Don’t optimize prematurely - Making the current component reusable with current variations known.
    不要过早优化. 只要求组件在当前需求下可被复用, 然后随机应变

    来自于react-bits

    可配置性

    明确知道该组件输入与输出,外部传入Props,和内部State状态。暴露的方法与数据的传递。

    生命周期

    一个好的组件有很强的生命周期管理,入参是什么,在每一个阶段该干什么。

    例如:
    React 中提供了一些生命周期函数:componentWillMount,componentDidMount,componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,componentDidUpdate,render,componentWillUnmount,componentDidCatch(React v16)。

    Vue 中提供了一些生命周期函数:beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed,errorCapture,errorCaptured(Vue v2.5)。

    一键换肤

    这个仅针对于UI组件,应前期规划好,为了后期换皮肤。

    国际化

    国际好有2个好处
    1.静态资源分离
    2.多语言

    总结

    如何写好一个组件是一个长久的话题,环境在变,写法在变,不变的是我们对优雅的追求。

    相关文章

      网友评论

          本文标题:如何写好一个组件

          本文链接:https://www.haomeiwen.com/subject/grhpfltx.html