基于Antd4 和React-hooks的项目开发

基于Antd4 和React-hooks的项目开发

https://github.com/dL-hx/react-cnode

项目依赖使用

  • react 16.13
  • react-redux 7.x
  • react-router-dom 5.x
  • redux 4.x
  • antd 4
  • axios
  • moment 2.24 (日期格式化)
  • qs

项目视图说明

  • 首页
  • 主题详情
  • 用户列表
  • 用户详情
  • 关于

配置按需加载

https://3x.ant.design/docs/react/use-with-create-react-app-cn#%E9%AB%98%E7%BA%A7%E9%85%8D%E7%BD%AE

$ yarn add react-app-rewired customize-cra

高级配置#

这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置,而且上面的例子加载了全部的 antd 组件的样式(gzipped 后一共大约 60kb)。

此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 react-app-rewired (一个对 create-react-app 进行自定义配置的社区解决方案)。

引入 react-app-rewired 并修改 package.json 里的启动配置。由于新的 react-app-rewired@2.x 版本的关系,你还需要安装 customize-cra。

$ yarn add react-app-rewired customize-cra
/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
}

然后在项目根目录创建一个 config-overrides.js 用于修改默认配置。

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  return config;
};

使用 babel-plugin-import#

注意:antd 默认支持基于 ES module 的 tree shaking,js 代码部分不使用这个插件也会有按需加载的效果。

babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件(原理),现在我们尝试安装它并修改 config-overrides.js 文件。

$ yarn add babel-plugin-import
+ const { override, fixBabelImports } = require('customize-cra');

- module.exports = function override(config, env) {
-   // do stuff with the webpack config...
-   return config;
- };
+ module.exports = override(
+   fixBabelImports('import', {
+     libraryName: 'antd',
+     libraryDirectory: 'es',
+     style: 'css',
+   }),
+ );

然后移除前面在 src/App.css 里全量添加的 @import '~antd/dist/antd.css'; 样式代码,并且按下面的格式引入模块。

  // src/App.js
  import React, { Component } from 'react';
- import Button from 'antd/es/button';
+ import { Button } from 'antd';
  import './App.css';

  class App extends Component {
    render() {
      return (
        <div className="App">
          <Button type="primary">Button</Button>
        </div>
      );
    }
  }

  export default App;

最后重启 yarn start 访问页面,antd 组件的 js 和 css 代码都会按需加载,你在控制台也不会看到这样的警告信息。关于按需加载的原理和其他方式可以阅读这里。

自定义主题#

按照 配置主题 的要求,自定义主题需要用到 less 变量覆盖功能。我们可以引入 customize-cra 中提供的 less 相关的函数 addLessLoader 来帮助加载 less 样式,同时修改 config-overrides.js 文件如下。

$ npm install less@3.9.0 less-loader@4.1.0 --save-dev
- const { override, fixBabelImports } = require('customize-cra');
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
-   style: 'css',
+   style: true,
  }),
+ addLessLoader({
+   javascriptEnabled: true,
+   modifyVars: { '@primary-color': '#1DA57A' },
+ }),
);

这里利用了 less-loader 的 modifyVars 来进行主题配置,变量和其他配置方式可以参考 配置主题 文档。

修改后重启 yarn start,如果看到一个绿色的按钮就说明配置成功了。

你也可以使用 craco 和 craco-antd 来实现和 customize-cra 一样的修改 create-react-app 配置的功能。

* react hooks 中的state使用

+   import { useSelector } from 'react-redux'
+   console.log(useSelector(state => state));
+   console.log(useSelector(state => state.topic));

+ // 获取search
+ import qs from 'qs';
+ const { search } = useLocation();
+ const { tab } = qs.parse(search.substr(1))

获取地址栏id参数

import { useParams } from 'react-router-dom';
let { id } = useParams()

获取history对象,返回上一页

import { useHistory } from 'react-router-dom';

let history = useHistory()
afterClose={()=>{
    history.goBack()
}}

配置页面整体布局和响应式处理方案

配置通用头部+Footer底部
组件基于bootstrap的响应式处理

列表实现

获取异步数据

如何获取异步数据,hooks写法与之前有何不同
数据和reducer进行关联

let getData = useTopicsList()
let {search} = useLocation()
let {tab, page} = qs.parse(search.substr(1));
useEffect(() => {// 调接口
getData(tab, page)
}, [tab, page]);
// ....

function useTopicsList() {
    const dispatch = useDispatch()
    return function (tab = "dev", page = 1, limit = 20, mdrender = false) {
        dispatch({
            type: 'topics_loading',
        })
        http.get(`/topics?tab=${tab}&page=${page}&limit=${limit}&mdrender=${mdrender}`)
            .then(res => {
                dispatch({// 存入state的数据
                    type: 'topics_loadover',
                    data: res.data.data
                })
            })
    }
}


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

moment转日期格式

dayjs处理时间
https://dayjs.fenxianglu.cn/category/display.html#%E6%A0%BC%E5%BC%8F%E5%8C%96

import dayjs from 'dayjs';
var relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(relativeTime)
require('dayjs/locale/zh-cn')
dayjs.locale('zh-cn')

  {/* 日期内容 */}
  {/* 返回现在到当前实例的相对时间。 */}
  {dayjs(last_reply_at).fromNow()}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分页

获取分类,点击分页时,修改地址栏参数(关联)
Pagination组件

import React from "react";
import { Pagination } from 'antd'
import { Link, useLocation } from 'react-router-dom'
import qs from 'qs'

// 获取分类,点击分页时,修改地址栏参数(关联)
export default function IndexPagination() {
    // 通过qs获取分类
    let { search } = useLocation();
    let { tab = "all", page = 1 } = qs.parse(search.substr(1));
    return <div className="index-pagination">
        <Pagination
            defaultCurrent={page}
            defaultPageSize={20}
            total={1000}
            showSizeChanger={false}
            itemRender={(page, type) => {
                switch (type) {
                    case 'page':
                        return <Link to={`/?tab=${tab}&page=${page}`}>{page}</Link>
                    case 'prev':
                        return <Link to={`/?tab=${tab}&page=${page}`}> {"<"} </Link>

                    case 'next':
                        return <Link to={`/?tab=${tab}&page=${page}`}> {">"}</Link>
                    default:
                        return <Link to={`/?tab=${tab}&page=${page}`}> {"..."}</Link>

                }
            }}
        />
    </div>
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

详情

封装时间组件

import dayjs from 'dayjs';
var relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(relativeTime)
require('dayjs/locale/zh-cn')
dayjs.locale('zh-cn')

// 处理时间的组件
export default function FromNow(props){
    let {date} = props
    return dayjs(date).fromNow()
}

使用

<FromNow date={create_at}/>
<FromNow date={last_reply_at}/>

评论列表组件

import React from 'react'
import {Avatar, Card, List, Comment} from "antd";
import {UserOutlined} from "@ant-design/icons";
import FromNow from "../../components/FromNow";
import {Link} from "react-router-dom";

export default function Replies(props) {
    let {data=[], loading} = props
    return <Card
        title="评论列表"
        loading={loading}
        id='replies'
    >
        <List
            dataSource={data}
            renderItem={(itemData) => {
                // console.log(itemData)
                return <List.Item>
                    <Comment
                        author={<Link to={`/user/${itemData.author.loginname}`}>{itemData.author.loginname}</Link>}
                        avatar={<Avatar
                            icon={<UserOutlined/>}
                            src={itemData.author.avatar_url}
                            title={itemData.author.loginname}
                        />}
                        content={<div
                            dangerouslySetInnerHTML={{
                                __html: itemData.content
                            }}
                        />
                        }
                        datetime={<time>发布于: <FromNow data={itemData.create_at}/></time>}
                    />
                </List.Item>
            }}
            pagination={{
                simple: true
            }}
        />
    </Card>
}

引用组件

  • <Replies data={data.replies} loading={loading}/>
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用户详情

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<TopicList loading={loading} data={recent_topics} />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/259552.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL进阶理论篇(十四):CBO优化器是如何计算代价的?

文章目录 简介能调整的代价模型的参数有哪些&#xff1f;mysql.server_costmysql.engine_cost 如何修改这些代价参数&#xff1f;代价模型具体是如何计算的参考文献 简介 大部分RDBMS都支持基于代价的优化器CBO&#xff0c;但其实CBO仍然存在缺陷&#xff08;比如参数配置的不…

RUST与RUSTful简介

RUST与RUSTful 1、背景2、RUST的起源3、RUST与RUSTful4、总结 1、背景 随着互联网&#xff08;Internet&#xff09;的发展&#xff0c;越来越多的人开始意识到&#xff0c;网站即软件&#xff0c;而且是一种新型的软件。这种"互联网软件"采用客户端/服务器&#xff…

外汇天眼:Cboe宣布与纽约州Secaucus的NY6数据中心建立连接

NY6数据中心将集成到Cboe的延迟均衡Secaucus基础架构中&#xff0c;目前该基础架构使用NY4和NY5数据中心。 NY6将仅作为BYX Equities、BZX Equities、EDGA Equities、EDGX Equities、BZX Options、EDGX Options和C2 Options交易所的延迟均衡出入口&#xff08;PoP&#xff09;…

Ubuntu-20.04.2 mate 上安装、配置、测试 qtcreator

一、从repo中安装 Ubuntu-20.04.2的repo中&#xff0c;qtcreator安装包挺全乎的&#xff0c;敲完 sudo apt install qtcreator 看一下同时安装和新软件包将被安装列表&#xff0c;压缩包252MB&#xff0c;解压安装后933MB&#xff0c;集大成的一包。 sudo apt install qtcrea…

JDK各个版本特性讲解-JDK11特性

JDK各个版本特性讲解-JDK11特性 一、JAVA11 概述二、语法层次的变化1. 局部变量类型推断升级 三、API层次的提升1. String新增的方法2. Optional新增方法3.HTTPClient 四、其他变化1. 更简化的编译运行2.ZGC3.其他了解 一、JAVA11 概述 2018年9月26日,Oracle官方发布JAVA11.这是…

【开源软件】最好的开源软件-2023-第三名 Docker

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

算法基础之约数之和

约数之和 核心思想&#xff1a; #include<iostream>#include<algorithm>#include<vector>#include<unordered_map>using namespace std;typedef long long LL;const int N 110 , mod 1e97;int main(){int n;cin>>n;unordered_map<int,int&…

支持向量机 支持向量机概述

支持向量机概述 支持向量机 Support Vector MachineSVM ) 是一类按监督学习 ( supervisedlearning)方式对数据进行二元分类的广义线性分类器 (generalized linear classifier) &#xff0c;其决策边界是对学习样本求解的最大边距超亚面 (maximum-margin hyperplane)与逻辑回归和…

Mybatis-Plus讲义v1.0

Mybatis-Plus 课程目标 了解Mybatis-Plus 整合Mybatis-Plus 通用CRUD Mybatis-Plus的配置 条件构造器 Mybatis-Plus 的Service封装 代码生成器 1 Mybatis-Plus介绍 1.1 Mybatis-Plus介绍 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&…

关于B+树的总结

B树(B-tree) B树属于多叉树又名平衡多路查找树&#xff08;查找路径不只两个&#xff09;&#xff0c;数据库索引技术里大量使用着B树和B树的数据结构 规则&#xff1a; &#xff08;1&#xff09;排序方式&#xff1a;所有节点关键字是按递增次序排列&#xff0c;并遵循左小…

MybatisPlus报错:BindingException: Invalid bound statement (not found): 的解决办法

当我们遇到这个报错的时候&#xff0c;通常意味着mapper的绑定出现了问题 我们需要检查相关的配置文件是否正确 本人使用MyBatisPlus时遇到了这个问题&#xff0c; BindingException: Invalid bound statement (not found): 通过检查映射发现没有问题 再检查namescape发现…

网络基础介绍

1.网线制作 1.1 网线制作需要的工具 网线 网线钳 水晶头 测试仪 ​编辑 1.2 网线的标准 1.3 网线的做法 2.集线器&交换机&路由器的介绍 3.OSI七层模型 4.路由器的设置 4.1 常见的路由器设置地址 4.2 常见的路由器账号密码 4.3 登录路由器 设置访客网…

算法02哈希法

算法01之哈希法 1.哈希法理论基础1.1哈希表&#xff08;1&#xff09;哈希表&#xff08;2&#xff09;哈希函数&#xff08;3&#xff09;哈希碰撞 1.2哈希法基本思想1.3哈希法适用场景与最常用的哈希结构 2.LeetCode242&#xff1a;有效的字母异位词&#xff08;1&#xff09…

Linux:终端定时自动注销

这样防止了&#xff0c;当我们临时离开电脑这个空隙&#xff0c;被坏蛋给趁虚而入 定几十秒或者分钟&#xff0c;如果这个时间段没有输入东西那么就会自动退出 全局生效 这个系统中的所有用户生效 vim /etc/profile在末尾加入TMOUT10 TMOUT10 这个就是10 秒&#xff0c;按…

【QT】Model/View结构

目录 1 概述 2 Mode/View基本原理 3 数据模型 4 视图组件 5 代理 6 Model/View结构的一些概念 6.1 Model/View的基本结构 6.2 模型索引 6.3 行号和列号 6.4 父项 6.5 项的角色 1 概述 Model/View&#xff08;模型/视图&#xff09;结构是Qt中用界面组件显示与编辑数据的一种结构…

在scrapy 使用selenium模拟登录获取cookie

前言 最近有一点点爬虫需求&#xff0c;想总结一下scrapy框架的一些基本使用方法&#xff0c;加深印象&#xff0c;自己一直习惯使用一些脚本文件运行爬虫&#xff0c;面对数据量非常大&#xff0c;稳定性要求比较高的&#xff0c;效率需求比较高的情况下还是用scrapy较为合适…

vue-springboot二手家电家用电器商城交易管理系统java毕业设计

本二手家电管理平台是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了用户和管理员这两者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能优化界…

final的详解

在Java中&#xff0c;final 关键字用于表示不可改变的实体&#xff0c;可以应用于变量、方法、类和指令重排序。它有不同的作用&#xff0c;具体取决于它被应用的上下文。 1.对于变量&#xff1a; 如果一个变量被声明为 final&#xff0c;则该变量的值在一旦被赋予后就不能再被…

C++共享和保护——(5)编译预处理命令

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 耕耘者的汗水是哺育种子成长的乳汁&am…

制造企业可以通过哪些措施改善设备OEE

设备综合效率OEE&#xff08;Overall Equipment Effectiveness&#xff09;是制造企业衡量设备效率的关键指标之一。高效的设备运行对于提高生产效率、降低成本和实现竞争优势至关重要。然而&#xff0c;实现高水平的设备OEE并不是一项简单的任务。本文将介绍一些制造企业可以采…