目录
一、组件库介绍
1、什么是组件
(1)工业:具有标准接口和某种功能且可复用的标准零部件
(2)软件开发:封装好的可复用的程序"零部件",像搭积木一样把不同功能的组件搭起来
(3)前端开发:UI组件,"按钮"、"输入框"、"下拉选择"都是组件,组件和组件组合就变成了一个更复杂的组件
2、组件库介绍
(1)组件库:就是一系列U组件的合集
(2)核心:其包含的每一个组件,都遵循同一套体系来实现的
(3)意义:提高统一的标准化规范
①一致性 ②效率 ③协同
3、arco.design
(1)认识
①生态平台:
主题配置平台:组件库的风格配置
物料市场:物料开发,在线托管
图标平台:图标资源的托管
设计资源库:插画、落地页、LOGO等设计资源
②资源+工具
③设计系统基础
(2)构建基于
①产出效率提升
②效率提升
③发效率提升
二、组件库的使用
有一个运营平台的项目,那么如何快速搭建起来?
1、快速上手
(1)安装
需要同时安装 react >= 16.8 和 react-dom >= 16.8
// npm
npm i @arco-design/web-react
// yarn
yarn add @arco-design/web-react
(2)基础使用:按钮的引入使用
javascript
import React from "react";
import ReactDOM from "react-dom";
import { Button } from "@arco-design/web-react";
import "@arco-design/web-react/dist/css/arco.css";
ReactDOM.render(
<Button type="primary">Hello Arco</Button>,
document.querySelector("#root")
);
(3)整个组件库都被打包到了js文件里面
占用空间,如何解决?
①按需加载:插件babel-plugin-import
javascript
npm i babel-plugin-import -D
②添加配置:在babel 配置中加入
javascript
plugins: [
[
'babel-plugin-import',
{
libraryName: '@arco-design/web-react',
libraryDirectory: 'es',
camel2DashComponentName: false,
style: true, // 样式按需加载
},
],
];
有效将体积降低96%,即3.12 MB =>123 KB
③解析:该插件帮我们将按钮例子的代码编译为按需引入的形式,能使未被使用的代码不被引入
(4)通过 CDN 使用
①开发环境: unpkg.com/@arco-desig...
②生产环境: unpkg.com/@arco-desig...
典型示例:CodePen,大多数组件库都会支持通过它打开示例代码
2、主题定制
(1)通过CSS进行样式覆盖
css
body {
--primary-1: 255,236,232;
--primary-2: 240,193,185;
--primary-3: 225,151,143;
--primary-4: 211,112,105;
--primary-5: 196,74,70;
--primary-6: 181,40,40;
--primary-7: 155,26,30;
--primary-8: 129,14,22;
--primary-9: 103,6,15;
--primary-10: 77,0,10;
}
body[arco-theme="dark"] {
--primary-1: 77,0,10;
--primary-2: 103,5,14;
--primary-3: 129,17,25;
--primary-4: 155,33,36;
--primary-5: 181,53,53;
--primary-6: 196,77,73;
--primary-7: 211,115,108;
--primary-8: 225,154,146;
--primary-9: 240,197,190;
--primary-10: 255, 240,237;
}
(2)修改Less变量
①在less文件里修改
javascript
@import '@arco-design/web-react/dist/css/index.less ';
@arcoblue-6: #b52828;
②在webpack.config.js或者在 Webpack 打包的时候,通过 less-loader 的modifyVars对所有的变量进行替换
javascript
module.exports = {
rules: [{
test: /.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'less-loader',
options: {
modifyVars: { // 在less-loader@6 modifyVars 配置被移到 lessOptions 中
'arcoblue-6': '#f85959',
},
javascriptEnabled: true
},
}],
...
}],
...
}
(3)组件定制
①例如:Button要带有投影效果,Input面性=>线性
②利用Arco Pro内置好的组件库,快速上手操作如下
官网https://link.juejin.cn/?target=https%3A%2F%2Farco.design%2Fdocs%2Fpro%2Fstart
javascript
预装环境
> npm i -g arco-cli
项目初始化
>arco init hello-arco-pro
项目开发
> cd hello-arco-pro
> yarn dev
③也可以通过DesignLab解决
3、暗黑模式
(1)组件库通过 body
标签上的 arco-theme
属性来标明当前的主题,只要修改这个属性,即可完成主题的切换
javascript
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
darkThemeMq.addListener(e => {
if (e.matches) {
// 设置为暗黑主题
document.body.setAttribute('arco-theme', 'dark');
} else {
// 恢复亮色主题
document.body.removeAttribute('arco-theme');
}
});
(2)局部应用暗色模式
①核心思路:本质上是控制暗色颜色变量的挂载位置,提高我们所需要的颜色变量的优先级
②控制暗色变量挂载到应用了暗黑样式的局部区域,对应的DOM标签上,实现该DOM下所有内容呈现暗色模式
4、语言国际化
(1)直接通过ConfgProvider组件传入不同语言文件去修改Locale
javascript
import { ConfigProvider } from '@arco-design/web-react';
import enUS from '@arco-design/web-react/es/locale/en-US';
import XXXLocale from '@arco-design/web-react/es/locale/xxx';
export function App( ) {
return (
<ConfigProvider locale={{ something ? enUS : XXXLocale }}>
{
// ...
}
</ConfigProvider>
);
}
(2)语言未支持
①模仿官方的语言文件格式,自定义语言文件
②当语言需求不支持时,可向组件库维护人员提需求,等官方维护者将语言安排上
(3)RTL 视图
①元素方向RTL:CSS属性direction: rtl;(用来设置文本和其他元素的默认方向是从右到左)
②布局RTL
css
margin-left => margin-right
position: right =>position: left
③交互行为RTL
Slider组件:向左拖动数值变小=>向右拖动数值变小
④其他处理
左还是左,右还是右:Notification设置为right弹出时,无论在 RTL还是LTR,都是出现在右上角
Arco 组件库 RTL 从 0 到 1https://link.juejin.cn?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%2FKyYV0dodxynoR6osXsNkFQ(4)ConfigProvider全局配置组件默认属性
①修改组件默认的属性值,从而改变组件的默认表现
②通过ConfigProvider 的 componentConfg 属性,传入定义好的配置文件,组件配置将会对ConfgPorvider 组件所包裹的所有组件生效
③ConfigProvider:是一个内置组件,利用React Context ,为所有组件提供统一的全局配置
5、业务常见问题
①旧项目迁移:Codemod代码迁移工具
②如何获取OnCall支持
③更新日志,发版周期
④如何参与共建
可以通过用户群、Github issue、官方文档站查阅资料
三、自定义组件
1、业务组件库搭建
(1)架构设计
①单包架构:一个代码仓库里所有组件打包成一个整体,发布出去一个npm包
使用方式:从一个包名里面引用了多个组件,去进行组合使用
javascript
import { From, Input, Button, Checkbox } from '@arco-design/web-react';
优点:
- 公共代码易复用
- 展示更聚合,便于维护
- 引入一个包即可使用全部组件
缺点:
- 修改一个组件需要更新整个库
- 需要考虑按需加载
②多包架构:一个代码仓库包含多个组件代码,会发布出去多个npm包
使用方式:组合使用多个组件的话,就必须从多个NPM包引入组件
javascript
import SelectWithCheckAll from '@arco-materials/select-with-check-all';
import ProRadio from '@arco-materails/pro-radio';
优点:
- 单独发包,升级灵活。
- 在同一仓库下,便于代码管理
- 使用者无需考虑按需加载
缺点:
- 组件间相互依赖时,需要通过npm 包引入
- 组合使用时需要安装每一个用到的npm包
(2)技术方案
①开发环境
- 打包速度
- 实时预览,如storybook
②样式方案
- 样式方案:Less / Sass,css in Js,cSS等
- 组件库换肤,样式定制等能力
③产物构建
- 建工具webpack , rollup,vite , gulp 等
- 产物格式:cjs , umd , es
④质量保障
- 测试工具: jest ,karma,mocha, enzyme,react-testing-library 等
- 测试类型:单元测试,快照测试,截屏测试,e2e测试等
(3)对外文档
①文档部署
- Demo展示:Storybook,umijs 等
- 静态内容:markdown
②组件API生成
- 手写
- 自动提取:ts-docuemnt等
③版本日志
- 手写
- 自动提取:从PR提交记录自动提取@arco-design/changelog
2、组件开发规范
(1)项目组织
①语义化命名
组件的命名应当具有语义,并且避免与基础组件冲突。同一团队/仓库下的业务组件,也可采用相同的命名前缀。
javascript
//Bad Case
function SelectV2(){}
//Good Case
function SelectWithCheckAll(){}
②包名和组件名一致
NPM包名应当尽量与组件名保持一致,包含明确的使用场景信息。
javascript
//Bad Case
select-v2
arco-materails
//Good Case
select-with-check-all
example-platform-materials-react
③单独维护类型文件
推荐将需要对外导出的TS类型维护在单独的interface.ts 中,并将其在index.ts 中导出
javascript
//Bad Case
//index.tsx
export interface
ButtonProps {
//...
}
export default function
Button() {}
//Good Case
//interface.ts
export interface ButtonProps {
//...
}
//index.tsx
import type { ButtonProps } from './interface.ts';
export default function Button() {}
export type { ButtonProps };
(2)组件设计
①接口定义
在为组件定义接口类型时,应继承原生DOM(或基础组件)属性,避免属性遗漏或重复声明。
javascript
//Bad Case
interface InputProps {}
interface SelectWithCheckAllProps {}
//Good Case
interface InputProps
extends InputHTMLAttributes<HTMLInputElement> {}
import { SelectProps } from '@arco-design/web-react';
interface SelectWithCheckAllProps extends SelectProps {}
②类名前缀统一
组件使用特殊且统一的类名前缀,尽量降低与用户类名冲突的可能性。
javascript
//Bad Case
function Button( ) {
return <button className="button-circle"/>;
}
//Good Case
const prefixCls = 'p-matirial';
function Button() {
return <button className={`${prefixCls}-button-circle`} />;
}
③避免行内样式和cSS Modules
确保外部可通过类名进行样式覆盖。
javascript
//Bad Case
function Button() {
return <button style={{ padding: 10 }} />;
}
//Good Case
function Button() {
return <button className="am-button" />;
}
@am-button-prefix-cls: ~'am-button ';
.@{am-button-prefix-cls} {
padding: 10px;
}
④避免在JS中直接引入样式文件
应尽量保证逻辑与样式的分离,确保用户可以分别引入JS和CSS文件,避免由于构建环境的不同导致的用户编译失败的问题。
javascript
//Bad Case
import './style/index.less';
function Button() {}
//Good Case
//Pure JS
function Button() {}
⑤注意组件样式的按需加载
在基于基础组件库如Arco进行业务组件的逻辑封装时,应注意按需引入所依赖的Arco基础组件的样式文件
javascript
//Bad Case
//select-with-check-all/style/index.js
//组件自身的样式文件
import './index.less';
//Good Case
//select-with-check-all/style/index.js
//SelectWithCheckAll组件依赖了arco的Select组件
import '@arco-design/web-react/es/Select/style/index.js'
import './index.less';
3、示例实践guide-tip
(1)功能要点
①控制引导气泡的出现
②点击下一步/上一步时切换气泡卡片的内容
③气泡卡片的位置跟随变动
④在最后一步时,显示完成按钮
(2)思路
①通过是否显示引导气泡,控制气泡显示/隐藏
②通过每个步骤的显示内容和指向的dom元素,控制气泡显示的内容
(3)API定义
javascript
/**
* @title GuideTip
*/
export interface GuideTipProps {
/**
* @zh是否显示引导气泡
*/
visible?: boolean;
/**
*@zh引导步骤
*/
steps?: {
title?: ReactNode;
content?: ReactNode;
target: ()=>HTMLElement
}[];
/**
*@zh完成时的回调
*/
onEnd?: () => void;
}
(4)核心逻辑
①显示弹出层:Arco Popover 组件
②步骤切换:状态变量 current 记录当前处于哪一步骤
③弹出层始终指向对应的 Button:实时获取目标节点的位置,更新弹出层指向。
javascript
const GuideTip = (props: GuideTipProps) => {
//使用自定义的类名前缀
const prefixcls = "m-guide-tip";
const { steps, visible } = props;
//标识当前展示的气泡内容索引
const [currentIndex, setCurrentIndex] = useState(-1);
const current = steps[currentIndexl;
//通过一定方式计算出 target 的位置,并应用在占位元素上,从而让弹出层能准确指向 target
const targetStyle = useMemo(() => {
if (!visible) {
return;
)
const target = steps[currentIndex]?.target?.();
if (target) {
const { width,height,left,top } = target.getBoundingClientRect();
return { width,height,left, top };
}
},[currentIndex,visible]);
useEffect(() => {
if (!visible) {
setCurrentIndex(-1);
}else {
setCurrentIndex(0);
,[visible]);
return {
<Popover
popupVisible={visible}-
}
>
<div className={`${prefixCls}-target`} style={targetStyle} />
</Popover>
};
}
4、业务组件快速托管
Arco CLl+物料平台:供标准的业务模块开发方案的脚手架工具承载通用业务模块展示的在线平台