React系列十二 - AntDesign UI庫
對於學習過程,不是特別建議從一開始就使用別人的第三方庫UI庫,更重要的是要學會組件化相關的知識(就想前面我們已經講了非常相關知識),之後自己來封裝、設計一套自己的可複用組件。
但是在公司開發爲了開發效率,我們往往也會選擇一些非常優秀的第三方UI庫,而AntDesign就是這樣的一套優秀的UI組件庫。
一. 認識AntDesign
1.1. AntDesign的介紹
AntDesign
,簡稱 antd
是基於 Ant Design 設計體系的 React UI 組件庫,主要用於研發企業級中後臺產品。
AntDesign的特點:
-
:rainbow: 提煉自企業級中後臺產品的交互語言和視覺風格。
-
:package: 開箱即用的高質量 React 組件。
-
使用 TypeScript 開發,提供完整的類型定義文件。
-
⚙️ 全鏈路開發和設計工具體系。
-
:earth_africa: 數十個國際化語言支持。
-
:art: 深入每個細節的主題定製能力。
全鏈路開發和設計指的是什麼?
-
全鏈路這個詞我記得是16年左右阿里提出的;
-
從
業務戰略—用戶場景—設計目標—交互體驗—用戶流程—預期效率
全方面進行分析和考慮; -
這個主要是產品經理會考慮的一個點;
AntDesign的兼容性:
-
現代瀏覽器和 IE11(需要 polyfills)。
-
支持服務端渲染。
-
Electron
[email protected]
之後不再支持 IE8, [email protected]
之後不再支持 IE9/10。
目前穩定的版本:v4.4.0
1.2. AntDesign的安裝
使用 npm 或 yarn 安裝
npm安裝:
npm install antd --save
yarn安裝:
yarn add antd
我們需要在index.js中引入全局的Antd樣式:
import "antd/dist/antd.css";
在App.js中就可以使用一些組件了:
考慮一個問題:Antd是否會將一些沒有用的代碼(組件或者邏輯代碼)引入,造成包很大呢?
antd
官網有提到: antd
的 JS 代碼默認支持基於 ES modules 的 tree shaking,對於 js 部分,直接引入 import { Button } from 'antd'
就會有按需加載的效果。
1.3. 高級配置
1.3.1. 認識craco
上面的使用過程是無法對主題進行配置的,好像對主題等相關的高級特性進行配置,需要修改create-react-app 的默認配置。
如何修改create-react-app 的默認配置呢?
-
前面我們講過,可以通過
yarn run eject
來暴露出來對應的配置信息進行修改; -
但是對於webpack並不熟悉的人來說,直接修改 CRA 的配置是否會給你的項目帶來負擔,甚至會增加項目的隱患和不穩定性呢?
-
所以,在項目開發中是不建議大家直接去修改 CRA 的配置信息的;
那麼如何來進行修改默認配置呢?社區目前有兩個比較常見的方案:
-
react-app-rewired + customize-cra;(這個是antd早期推薦的方案)
-
craco;(目前antd推薦的方案)
第一步:安裝craco:
yarn add @craco/craco
第二步:修改package.json文件
-
原本啓動時,我們是通過react-scripts來管理的;
-
現在啓動時,我們通過craco來管理;
"scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", + "start": "craco start", + "build": "craco build", + "test": "craco test", }
第三步:在根目錄下創建craco.config.js文件用於修改默認配置
module.exports = { // 配置文件 }
1.3.2. 配置主題
按照 配置主題 的要求,自定義主題需要用到類似 less-loader 提供的 less 變量覆蓋功能:
-
我們可以引入 craco-less 來幫助加載 less 樣式和修改變量;
安裝 craco-less
:
yarn add craco-less
修改craco.config.js中的plugins:
-
使用
modifyVars
可以在運行時修改LESS變量;
const CracoLessPlugin = require('craco-less'); module.exports = { plugins: [ { plugin: CracoLessPlugin, options: { lessLoaderOptions: { lessOptions: { modifyVars: { '@primary-color': '#1DA57A' }, javascriptEnabled: true, }, }, }, }, ], }
引入antd的樣式時,引入antd.less文件:
// import "antd/dist/antd.css"; import 'antd/dist/antd.less';
修改後重啓 yarn start
,如果看到一個綠色的按鈕就說明配置成功了。
1.3.3. 配置別名
在項目開發中,某些組件或者文件的層級會較深,
-
如果我們通過上層目錄去引入就會出現這樣的情況:
../../../../components/button
; -
如果我們可以配置別名,就可以直接從根目錄下面開始查找文件:
@/components/button
,甚至是:components/button
;
配置別名也需要修改webpack的配置,當然我們也可以藉助於 craco 來完成:
... const path = require("path"); const resolve = dir => path.resolve(__dirname, dir); module.exports = { ... , webpack: { alias: { '@': resolve("src"), 'components': resolve("src/components"), } } }
在導入時就可以按照下面的方式來使用了:
import HYCommentInput from '@/components/comment-input'; import HYCommentItem from 'components/comment-item';
二. AntDesign案例
我們通過AntDesign來編寫一個案例:
1.1. 案例-評論框
我們選來完成評論框,評論框有兩部分組成:
-
TextArea的輸入框:Input.TextArea;
-
提交評論的按鈕:Button;
import React, { PureComponent } from 'react'; import moment from 'moment'; import { Form, Button, Input } from 'antd'; export default class HYCommentInput extends PureComponent { constructor(props) { super(props); this.state = { value: "" } } render() { return ( <div> <Input.TextArea rows={4} onChange={this.onChange.bind(this)} value={this.state.value} /> <Button onClick={this.onSubmit.bind(this)} type="primary"> 添加評論 </Button> </div> ) } onChange(e) { this.setState({ value: e.target.value }) } onSubmit() { console.log(this.state.value, moment().fromNow()); const commentInfo = { id: Date.now(), name: "coderwhy", avatar: "https://upload.jianshu.io/users/upload_avatars/1102036/c3628b478f06.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240", content: <p>{this.state.value}</p>, datetime: moment() } this.props.submitComment(commentInfo); this.setState({ value: "" }); } }
1.2. 案例-評論列表
評論列表主要是使用Comment組件,Comment組件有一些屬性:
-
author:展示作者的名稱;
-
avatar:展示作者的頭像;
-
可以使用Avatar的組件進行展示;
-
content:展示評論的內容;
-
datetime:展示評論的時間:
-
這裏我們可以使用Tooltip組件,當鼠標放在上面時,會顯示對應的title內容;
-
actions:評論下方的操作按鈕;
-
這裏我們可以使用DeleteOutlined,但是它來自
@ant-design/icons
,需要我們進行安裝;
import React, { PureComponent } from 'react'; import { Comment, Avatar, Tooltip } from "antd"; import { DeleteOutlined } from "@ant-design/icons"; export default class HYCommentItem extends PureComponent { render() { const { comment } = this.props; return ( <Comment author={<a href="/#">{comment.name}</a>} avatar={ <Avatar src={comment.avatar} alt={comment.name} /> } content={comment.content} datetime={ <Tooltip title={comment.datetime.format('YYYY-MM-DD HH:mm:ss')}> <span>{comment.datetime.fromNow()}</span> </Tooltip> } actions={ this.getActions() } /> ) } getActions() { return [ <span onClick={this.props.removeItem}><DeleteOutlined/> 刪除</span> ] } }
1.3. 案例-App組件
我們在App組件中,使用封裝的兩個組件:
import React, { PureComponent } from 'react'; import HYCommentInput from './components/comment-input'; import HYCommentItem from './components/comment-item'; export default class App extends PureComponent { constructor(props) { super(props); this.state = { commentList: [] } } render() { return ( <div style={{width: "500px", padding: "20px"}}> { this.state.commentList.map((item, index) => { return <HYCommentItem key={item.id} comment={item} index={index} removeItem={e => this.removeItem(index)}/> }) } <HYCommentInput submitComment={this.submitComment.bind(this)}/> </div> ) } submitComment(comment) { this.setState({ commentList: [...this.state.commentList, comment] }) } removeItem(index) { const newCommentList = [...this.state.commentList]; newCommentList.splice(index, 1); this.setState({ commentList: newCommentList }) } }