百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

细说前端开发UI公共组件的新认识「实践」

connygpt 2024-08-20 13:59 4 浏览


作者: 彭道宽

转发链接:https://mp.weixin.qq.com/s/dtmZv4YcQitbKajjNbW_Pg

前言

?

我除了菜,啥都不是

?

前段时间,组里决定做一个跨项目、跨业务的 UI 组件库,原因是我们部门的产品越来越多,且每个产品设计到多端(如 Web/Mobile/PC/Android 等)而为了快速响应目标,决定做一套统一且可视化的,拥有部门特色的 UI 组件库。

视觉已经给出了所有组件样式、交互效果,而我们前端组内部也经过一轮轮的评审和讨论,最终每个人都分了几个组件进行开发。而我呢,也分到了几个组件,有稍微简单点的,有存在复杂交互及状态的,这篇文章,主要是记录自己「第一次」开发一个公共组件的思考~

?

我负责的组件是 : Skeleton 骨架占位组件 、Card 卡片组件、Button 按钮组件、栅格组件

?

前期准备工作

这属于第一次开发公共组件,之前呢主要都还是在项目里边,抽离一些简单复用逻辑的业务组件,举个例子,对于 Button 组件,与我来说,我之前更多可能考虑的就只是一些常用的状态,比如说之前的Button组件代码是这样的 :

/**
 * @class Button
 * @extends {React.Component}
 * @property {string} text - 按钮文本
 * @property {string} size - 按钮大小,small/middle/big
 * @property {string} icon - 按钮携带的icon,不需要则为空
 * @property {string} color - 类型,可选值为 orange/ghost/white
 * @property {object} style - 样式
 * @property {string} textSize - 按钮文案文字大小,small/middle/big/super
 * @property {boolean} disabled - 可否点击
 * @property {string} iconSeat - 按钮icon的位置,left/right
 * @property {function} onHandleClick - 点击事件
 * @property {boolean} isLock - 是否锁定点击(注:如果需要使用锁,请保证所有操作为同步或者所有的异步行为执行完再return)
 */

这是我结合业务内容,抽离的Button组件,有一丝丝公共组件的样子,但是其实还是远远不够的。于是,此次在开发公共组件之前,我特意的去做了充足的准备。

组件化开发

什么是组件化?这个问题相信大部分前端工程师都知道~ 在跟我小学弟学妹们装 X 的时候,他们问我,什么是组件,我笑而不语,甩出了www.baidu.com网址,告诉他们,自己查...

?

组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程,有多种属性、状态反映其内部特性。

?

简单来说,我们可以把页面当作是变形金刚,由各不同零件组件,比如说 Header零件、Hand零件、Footer零件等...

然后呢,在我们想要制造一个变形金刚时,直接就用这些零件,就能快速 do 出一个产品了~

设计原则

相信大家也不想听我逼逼,直接进入主题,我想要设计一个大家都能普遍使用的组件,我该如何去设计,我上网搜了许多相关的文章,例如 :

在我看了一些文章之后,整理了一些其它人对组件设计的看法(底部会贴出友情链接),首先,我们得拥有一套组件化设计思维,要它有啥用?它能帮我们高效开发哦~

官方文档

这个文档必须详细,不然别人咋看,同时每一个组件,都应尽可能的表达,该组件的由来、使用场景、如何设计、API、传参等

?

感兴趣的可以去看看 ant design 的文档,它除了使用文档,在 github 上还有每个组件的说明文档

?

代码阅览

应该提供一个可以让开发者实时调试代码的地方,使其他这些组件的使用者可以更好地理解各个 props,相信比较流行热门的 UI 库,都有这种骚操作~

使用实例

提供一些如何将其数据导入 UI 的实例代码,使其他开发者可以更快上手与他们的使用情况。

如何设计

  1. 标准性
  2. 独立性
  3. 复用与易用
  4. 无环依赖原则(ADP)
  5. 入口处检查参数的有效性,出口处检查返回的正确性
  6. 稳定抽象原则(SAP)
  7. ......

上边如何设计我坦白,是从 聊聊组件设计 写过来的,懒得写了~(尊重作者,尊重原创,大家直接去看他的文章哈~)

着手开发

我们组里的组件库,是基于 Ant Design 进行开发,嗯,我一开始以为是项目中已经 npm install antd 了,谁知道当我去看 package.json时,发现并没得,于是我去问了一下负责这个组件库的 C 同学,原来...是要我们去看 Ant Design 的代码, 然后借鉴一波,去除国际化、还有一些不同的差异项,再加入自己部门特色的交互、样式~

奥力给,这啥啊,什么玩意啊,就直接去看源码了 ???

于是,我从我负责的组件里边,挑选了一个最简单的 Card 组件,进行研究了一波,wc,不看不知道,一看吓一跳...原来我还是太菜了...

这个卡片组件,如果没看源码之前,我估计就是这样 :

/** * @class Button * @extends {React.Component} * @property {string} text - 按钮文本 * @property {string} size - 按钮大小,small/middle/big * @property {string} icon - 按钮携带的icon,不需要则为空 * @property {string} color - 类型,可选值为 orange/ghost/white * @property {object} style - 样式 * @property {string} textSize - 按钮文案文字大小,small/middle/big/super * @property {boolean} disabled - 可否点击 * @property {string} iconSeat - 按钮icon的位置,left/right * @property {function} onHandleClick - 点击事件 * @property {boolean} isLock - 是否锁定点击(注:如果需要使用锁,请保证所有操作为同步或者所有的异步行为执行完再return) */

沿着这个思路,一路走下去,发现,如果传 content 肯定不对啊,为啥,如果用户想改这个文案内容的样式呢,简单,给他开放一个 contentStyle就好了嘛~

那如果用户想换行,又该咋办,简单,这个 content<String> 就改成 content<Array> 嘛,判断 typeof content,如果是数组就遍历渲染文案~

那如果用户传ReactNode类型的呢,比如这样

const loadingNode = (
  <div>loading</div>
)

<Card content={loadingNode} />

再或者,用户想这样~

const loadingNode = `<p className="loading">我是loading</p>`;

<Card content={loadingNode} />;

用户真实想要的是,你通过 dangerouslySetInnerHTML 进行转义,而不是你直接显示这个 content。

算了不想了,直接去看源码吧 ~

看源码的痛

初次一看,啥啊,这个 config-provider 是个啥玩意?这个 SizeContext 又是个啥,这个 less 文件咋都是用的 @xxx啊,怎么一个文件引入的这么多变量,都是外部的。

?

当我去看了 React 实战:设计模式和最佳实践 这本小册之后,我知道了,这 config-provider、ConfigConsumer 是个啥玩意。,然后在看完一个完整组件之后,才发现,Ant Design B !!!

?

「以我自己开发的 Card 组件来举例~」 , 我们先来共识一下,这个组件的一些样式

属性



然后呢,我们通过引入 import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'进行处理,「别问,问就是还没咋搞懂,总之就是高阶组件的疯狂操作,感兴趣的可以去看看,这个玩意真的有点意思」 config-provider

我们接着对一些 props 进行处理 ~

// 获取前缀,比如像ant-design一样,所有的class都是以 antd- 开头
const prefixCls = getPrefixCls('card', customizePrefixCls);

// 定义头部
let head: React.ReactNode;

// 定义加载时的状态
let loadingBlock: React.ReactNode;

if (title || extra) {
  head = (
    <div
      style={headStyle}
      className={`${prefixCls}-head ${headWrapName && headWrapName}`}
    >
      <div className={`${prefixCls}-head-wrapper`}>
        {title && <div className={`${prefixCls}-head-title`}>{title}</div>}
        {extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
      </div>
    </div>
  );
}

const body = (
  <div className={`${prefixCls}-body`}>{loading ? loadingBlock : children}</div>
);

在我们导出之前,我们通过SizeContext高阶组件进行包装~

<SizeContext.Consumer>
  {size => {
    // 如果你有自定义的size,以你的为准,没有则以SizeContext中默认的size
    const mergedSize = customizeSize || size;

    // 处理所有的className
    const classString = classNames(prefixCls, className, {
      [`${prefixCls}-loading`]: loading,
      [`${prefixCls}-shadow`]: isShadow,
      [`${prefixCls}-${mergedSize}`]: mergedSize
    });

    return (
      <div className={classString} style={style} onClick={onClick && onClick}>
        {head}
        {body}
      </div>
    );
  }}
</SizeContext.Consumer>

对于样式,不是直接在 less 文件写一些 color 或者 font-size 的,对于ant-design来说,他们有一个 style 文件,里边存放着许多定义好的变量,甚至于 theme 文件,可以说,到时候如果想自定义主题,只需要将其中的 theme 文件 copy 一份,然后进行修改,就能直接完成自定义主题的需求了~

怎么说呢,其实抽离了一些复杂的需求出去之后,相对的这个 Card 组件就简单了很多,我们再多去看看几个组件,会发现,真香,原来组件还可以这么设计,相对自己之前设计的那些low B组件,这个组件看起来就高大上太多了。

后续

回过头来看,这篇文章有点像随手写的笔记,没得啥干货,不过「主要的目的还是想传递给大家一个思想:就是有时间,可以考虑去看看一些优秀组件的源码」~ 奥力给 !

「 更新一下,这是后记,我再也不敢说我会写前端 Button组件「实践」,这是我开发Button组件遇到的问题和思考,希望对你们有点用~

目前进度

组内目前的一个进度也在有序进行中,毕竟大家都一致认同这个项目,且 v1 版本相对较为宽松,先出基础版,再深挖细节和优化 ~

推荐JavaScript经典实例学习资料文章

细说DOM API中append和appendChild的三个不同点

细品淘系大佬讲前端新人如何上王者「干货」

一文带你彻底解决背景跟随弹窗滚动问题「干货」

推荐常用的5款代码比较工具「值得收藏」

Node.js实现将文字与图片合成技巧

爱奇艺云剪辑Web端的技术实现

我再也不敢说我会写前端 Button组件「实践」

NodeX Component - 滴滴集团 Node.js 生态组件体系「实践」

Node Buffers 完整指南

推荐18个webpack精美插件「干货」

前端开发需要了解常用7种JavaScript设计模式

浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务

了不起的 Webpack HMR 学习指南(上)「含源码讲解」

了不起的 Webpack HMR 学习指南(下)「含源码讲解」

10个打开了我新世界大门的 WebAPI(上)「实践」

10个打开了我新世界大门的 WebAPI(中)「实践」

10个打开了我新世界大门的 WebAPI(下)「实践」

「图文」ESLint 在中大型团队的应用实践

Deno是代码的浏览器,你认同吗?

前端存储除了 localStorage 还有啥?

Javascript 多线程编程?的前世今生

微前端方案 qiankun(实践及总结)

「图文」V8 垃圾回收原来这么简单?

Webpack 5模块联邦引发微前端的革命?

基于 Web 端的人脸识别身份验证「实践」

「前端进阶」高性能渲染十万条数据(时间分片)

「前端进阶」高性能渲染十万条数据(虚拟列表)

图解 Promise 实现原理(一):基础实现

图解 Promise 实现原理(二):Promise 链式调用

图解 Promise 实现原理(三):Promise 原型方法实现

图解 Promise 实现原理(四):Promise 静态方法实现

实践教你从零构建前端 Lint 工作流「干货」

高性能多级多选级联组件开发「JS篇」

深入浅出讲解Node.js CLI 工具最佳实战

延迟加载图像以提高Web网站性能的五种方法「实践」

比较 JavaScript 对象的四种方式「实践」

使用Service Worker让你的 Web 应用如虎添翼(上)「干货」

使用Service Worker让你的 Web 应用如虎添翼(中)「干货」

使用Service Worker让你的 Web 应用如虎添翼(下)「干货」

前端如何一次性处理10万条数据「进阶篇」

推荐三款正则可视化工具「JS篇」

如何让用户选择是否离开当前页面?「JS篇」

JavaScript开发人员更喜欢Deno的五大原因

仅用18行JavaScript实现一个倒数计时器

图文细说JavaScript 的运行机制

一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索

推荐Web程序员常用的15个源代码编辑器

10个实用的JS技巧「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」

细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」

深入JavaScript教你内存泄漏如何防范

手把手教你7个有趣的JavaScript 项目-上「附源码」

手把手教你7个有趣的JavaScript 项目-下「附源码」

JavaScript 使用 mediaDevices API 访问摄像头自拍

手把手教你前端代码如何做错误上报「JS篇」

一文让你彻底搞懂移动前端和Web 前端区别在哪里

63个JavaScript 正则大礼包「值得收藏」

提高你的 JavaScript 技能10 个问答题

JavaScript图表库的5个首选

一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法

可视化的 JS:动态图演示 - 事件循环 Event Loop的过程

教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」

可视化的 js:动态图演示 Promises & Async/Await 的过程

原生JS封装拖动验证滑块你会吗?「实践」

如何实现高性能的在线 PDF 预览

细说使用字体库加密数据-仿58同城

Node.js要完了吗?

Pug 3.0.0正式发布,不再支持 Node.js 6/8

纯JS手写轮播图(代码逻辑清晰,通俗易懂)

JavaScript 20 年 中文版之创立标准

值得收藏的前端常用60余种工具方法「JS篇」

箭头函数和常规函数之间的 5 个区别

通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events

「前端篇」不再为正则烦恼

「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能

深入细品浏览器原理「流程图」

JavaScript 已进入第三个时代,未来将何去何从?

前端上传前预览文件 image、text、json、video、audio「实践」

深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系

推荐13个有用的JavaScript数组技巧「值得收藏」

前端必备基础知识:window.location 详解

不要再依赖CommonJS了

犀牛书作者:最该忘记的JavaScript特性

36个工作中常用的JavaScript函数片段「值得收藏」

Node + H5 实现大文件分片上传、断点续传

一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」

【实践总结】关于小程序挣脱枷锁实现批量上传

手把手教你前端的各种文件上传攻略和大文件断点续传

字节跳动面试官:请你实现一个大文件上传和断点续传

谈谈前端关于文件上传下载那些事【实践】

手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件

最全的 JavaScript 模块化方案和工具

「前端进阶」JS中的内存管理

JavaScript正则深入以及10个非常有意思的正则实战

前端面试者经常忽视的一道JavaScript 面试题

一行JS代码实现一个简单的模板字符串替换「实践」

JS代码是如何被压缩的「前端高级进阶」

前端开发规范:命名规范、html规范、css规范、js规范

【规范篇】前端团队代码规范最佳实践

100个原生JavaScript代码片段知识点详细汇总【实践】

关于前端174道 JavaScript知识点汇总(一)

关于前端174道 JavaScript知识点汇总(二)

关于前端174道 JavaScript知识点汇总(三)

几个非常有意思的javascript知识点总结【实践】

都2020年了,你还不会JavaScript 装饰器?

JavaScript实现图片合成下载

70个JavaScript知识点详细总结(上)【实践】

70个JavaScript知识点详细总结(下)【实践】

开源了一个 JavaScript 版敏感词过滤库

送你 43 道 JavaScript 面试题

3个很棒的小众JavaScript库,你值得拥有

手把手教你深入巩固JavaScript知识体系【思维导图】

推荐7个很棒的JavaScript产品步骤引导库

Echa哥教你彻底弄懂 JavaScript 执行机制

一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧

深入解析高频项目中运用到的知识点汇总【JS篇】

JavaScript 工具函数大全【新】

从JavaScript中看设计模式(总结)

身份证号码的正则表达式及验证详解(JavaScript,Regex)

浏览器中实现JavaScript计时器的4种创新方式

Three.js 动效方案

手把手教你常用的59个JS类方法

127个常用的JS代码片段,每段代码花30秒就能看懂-【上】

深入浅出讲解 js 深拷贝 vs 浅拷贝

手把手教你JS开发H5游戏【消灭星星】

深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】

手把手教你全方位解读JS中this真正含义【实践】

书到用时方恨少,一大波JS开发工具函数来了

干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)

手把手教你JS 异步编程六种方案【实践】

让你减少加班的15条高效JS技巧知识点汇总【实践】

手把手教你JS开发H5游戏【黄金矿工】

手把手教你JS实现监控浏览器上下左右滚动

JS 经典实例知识点整理汇总【实践】

2.6万字JS干货分享,带你领略前端魅力【基础篇】

2.6万字JS干货分享,带你领略前端魅力【实践篇】

简单几步让你的 JS 写得更漂亮

恭喜你获得治疗JS this的详细药方

谈谈前端关于文件上传下载那些事【实践】

面试中教你绕过关于 JavaScript 作用域的 5 个坑

Jquery插件(常用的插件库)

【JS】如何防止重复发送ajax请求

JavaScript+Canvas实现自定义画板

Continuation 在 JS 中的应用「前端篇」

作者: 彭道宽

转发链接:https://mp.weixin.qq.com/s/dtmZv4YcQitbKajjNbW_Pg

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&amp;Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick &#39;n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...