npm i -g create-react-app
// 初始化项目
npx create-react-app 项目名称
// 引入antdesign, sass, react-router-dom, axios等需要的依赖
yarn add ...
// 默认指令启动项目
yarn start
// 有些没用的目录可以删掉, 再自行添加一些其他的目录结构
// index.js 入口
import React from 'react';
import ReactDOM from 'react-dom/client';
import 'antd/dist/antd.min.css'
// 后导入全局样式文件,防止样式覆盖
import './index.scss';
import App from './App';
// 性能指标相关的,可以先去掉
import reportWebVitals from './reportWebVitals';
// 内部实现是用了 history 这个库和 React Context 来实现的,所以当你的用户前进后退时,history 这个库会记住用户的历史记录,这样需要跳转时可以直接操作
import { BrowserRouter as Router } from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Router>
<App />
</Router>
);
// 这样控制台可以打印出相关性能数据,小瞄一眼
reportWebVitals(console.log);
// App.js
import { useRoutes } from "react-router-dom";
import { routers } from "./routers/router";
function App() {
// 返回与当前位置匹配的路由元素,参数: 创建的路由对象
return useRoutes(routers);
}
export default App;
// router/index.js 管理路由组件
import AppLayout from '../views/layout/index';
import Menu11 from '../views/menu1/menu1-1'
import Menu22 from '../views/menu1/menu2-2'
import Login from '../views/login'
import Home from '../views/home'
export const routers = [
{
path: '/',
element: <AppLayout />,
// 路由嵌套,子路由的元素需使用<Outlet />
children: [
{
index: true,
element: (<Home />)
},
{
path: '/Menu11',
element: (<Menu11 />)
},
{
path: '/Menu22',
element: (<Menu22 />)
}
]
},
{
path: '/login',
element: (<Login />)
}
]
// layout.js 组件
import { Breadcrumb, Layout, Menu } from "antd";
import { MailOutlined, RedditOutlined } from "@ant-design/icons";
import React, { useState } from "react";
import { Outlet, useNavigate, } from "react-router-dom";
// 根目录 @ 要配置
import "@/styles/index.scss";
const { Header, Content, Sider, Footer } = Layout;
function getItem(label, key, icon, children, type) {
return {
key,
icon,
children,
label,
type,
};
}
const items1 = ["1", "2", "3"].map((key) => ({
key,
label: `nav ${key}`,
}));
// key值和router中定义相同
const items = [
getItem("Menu One", "Menu1", <MailOutlined />,
[getItem("Menu1", "/Menu11"), getItem("Menu2", "/Menu22")]
),
];
const rootSubmenuKeys = ["Menu1"];
const App = () => {
const [openKeys, setOpenKeys] = useState(["Menu1"]);
const onOpenChange = (keys) => {
const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1);
if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
setOpenKeys(keys);
} else {
setOpenKeys(latestOpenKey ? [latestOpenKey] : []);
}
};
const Navigate = useNavigate();
const toPage = (e) => {
Navigate(e.key);
};
return (
<Layout style={{ height: "100%" }}>
<Header className="header">
<RedditOutlined style={{ fontSize: "66px" }} />
<Menu
theme="light"
mode="horizontal"
defaultSelectedKeys={["2"]}
items={items1}
style={{ flex: "1" }}
/>
</Header>
<Layout>
<Sider width={200} className="site-layout-background">
<Menu
mode="inline"
openKeys={openKeys}
onOpenChange={onOpenChange}
style={{ height: "100%", borderRight: 0 }}
items={items}
onClick={toPage}
/>
</Sider>
<Layout
style={{
padding: "0 24px",
}}
>
<Breadcrumb
style={{
margin: "16px 0",
}}
>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Content
className="site-layout-background"
style={{
padding: 24,
margin: 0,
minHeight: 280,
}}
>
{/* 这里注意!之前没有写<Outlet /> 在路由上浪费了好多时间 */}
<Outlet />
</Content>
</Layout>
</Layout>
<Footer
style={{
textAlign: "center",
}}
>
react_demo ©2022 Created by Arbor
</Footer>
</Layout>
);
};
export default App;
关于webpack配置问题
脚手架创建的react项目初始化是没有webpack.config.js等相关配置文件的,默认都是隐藏的
初始package.json文件,配置的命令都是 “react-scripts *” 来执行的
// 这个命令就是提供出来 生成一个config目录,相关的配置文件都在内
// yarn eject 是不可逆操作
"eject": "react-scripts eject",
第一步主要是想设置一个根路径,没有用 eject 重写配置可以使用 craco 来覆盖
// 安装craco相关依赖
yarn add @craco/craco craco-less @babel/plugin-proposal-decorators babel-plugin-import
// package.json
"scripts": {
"start": "set PORT=5000 && craco start",
"build": "craco build",
"test": "craco test"
},
// craco.config.js
const path = require("path")
// 定义函数resolve, 将自定义的路径和js的根路径拼接起来
const resolve = (dir) => path.resolve(__dirname, dir);
module.exports = {
webpack:{
alias:{
"@": resolve("src")
}
},
}