React学习笔记05-React-Ant-Design

young 820 2022-09-30

AntDesign介绍

官网地址:https://ant.design/

浏览器兼容:

  • 现代浏览器和IE11(需要polyfills)
  • 支持服务端渲染
  • Electron

antd@2.0之后不再支持IE8,antd@4.0之后不再支持IE9/10

AntDesign安装

使用npm或者yarn安装

npm install antd --save

yarn add antd

需要在index.js中引入全局的Antd样式

import "antd/dist/antd.css";

Antd是否会将一些没用到的代码(组件或者逻辑代码)引入,造成包很大?

antd官网有提到,antd的JS代码默认支持基于ES modules的tree shaking,对于js部分,直接引入 import {Button} from ‘antd’ 就会有按需加载的效果。

craco

在使用antd的过程中,是无法对主题进行配置的,对主题等相关的高级特性进行配置,需要修改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-scrips来管理的,现在通过craco来管理

"scripts":{
  "start": "react start",
  "build": "react build",
  "test": "react test",
}

改为

"scripts":{
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
}

在根目录下创建craco.config.js文件用于修改默认配置

module.exports = {
	// 配置文件
}

主题配置

官网教程:https://ant.design/docs/react/customize-theme-cn

按照主题配置的要求,自定义主题需要用到类似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/andt.less'

修改之后重新启动,就可以看到主题从蓝色变成了绿色

配置别名

在项目开发中,某些组件或者文件的层级会比较深,如果通过生成目录去引入,就会出现

../../../component/button的情况。

如果我们配置别名,就可以直接从根目录开始查找文件,比如@/component/button

配置别名也需要修改webpack配置,我们也可以借助craco来完成

const CracoLessPlugin = require('craco-less');
const path = require("path");
const resolve = dir => path.resolve(__dirname, dir);

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@primary-color': '#1DA57A' },
            javascriptEnabled: true,
          },
        },
      },
    }
  ],
  webpack: {
    alias: {
      "@": resolve("src"),
      "components": resolve("src/components")
    }
  }
}

AntDesign案例

App.js

import React, { PureComponent } from 'react';

import CommentInput from './components/CommentInput';
import CommentItem from './components/CommentItem';

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 <CommentItem key={item.id} 
                                comment={item} 
                                removeItem={e => this.removeComment(index)}/>
          })
        }
        <CommentInput submitComment={this.submitComment.bind(this)}/>
      </div>
    )
  }

  submitComment(info) {
    this.setState({
      commentList: [...this.state.commentList, info]
    })
  }

  removeComment(index) {
    const newCommentList = [...this.state.commentList];
    newCommentList.splice(index, 1);
    this.setState({
      commentList: newCommentList
    })
  }
}

CommentItem.js

import React, { PureComponent } from 'react';

import {
  Comment,
  Avatar,
  Tooltip
} from "antd";
import { DeleteOutlined } from "@ant-design/icons";

export default class CommentItem extends PureComponent {
  render() {
    const { nickname, avatar, content, datetime } = this.props.comment;

    return (
      <Comment
        author={<a href="/#">{nickname}</a>}
        avatar={<Avatar src={avatar} alt={nickname} />}
        content={<p>{content}</p>}
        datetime={
          <Tooltip title={datetime.format("YYYY-MM-DD")}>
            <span>{datetime.fromNow()}</span>
          </Tooltip>
        }
        actions={[
          <span onClick={e => this.removeItem()}><DeleteOutlined />删除</span>
        ]}
      />
    )
  }

  removeItem() {
    this.props.removeItem();
  }
}

CommentInput.js

import React, { PureComponent } from 'react';

import moment from 'moment';

import { Input, Button } from "antd";

export default class CommentInput extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      content: ""
    }
  }

  render() {
    return (
      <div>
        <Input.TextArea rows={4} 
                        value={this.state.content}
                        onChange={e => this.handleChange(e)}/>
        <Button type="primary" onClick={e => this.addComment()}>添加评论</Button>
      </div>
    )
  }

  handleChange(event) {
    this.setState({
      content: event.target.value
    })
  }

  addComment() {
    const commentInfo = {
      id: moment().valueOf(),
      avatar: "https://upload.jianshu.io/users/upload_avatars/1102036/c3628b478f06.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240",
      nickname: "coderwhy",
      datetime: moment(),
      content: this.state.content,
      comments: [
        
      ]
    }

    this.props.submitComment(commentInfo);

    this.setState({
      content: ""
    })
  }
}