一. 创建项目
- 使用 React CLI 搭建项目:
npx create-react-app geek-pc
- 进入项目根目录:
cd geek-pc
- 启动项目:
npm run start
- 调整项目目录结构:
/src
/assets # 项目资源文件,比如,图片 等
/components # 通用组件
/pages # 页面
/utils # 工具,比如,token、axios 的封装等、
/api # 封装接口
App.js # 根组件
index.css # 全局样式
index.js # 项目入口
index.js
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
ReactDOM.render(
<App />
,
document.getElementById('root')
)
index.css
* {
margin: 0;
padding: 0;
list-style: none;
}
#root,
.app {
height: 100%;
}
1.1创建组件并配置基础路由
|-src
|-pages
|-Layout/index.jsx # 布局页
|-Login/index.jsx # 登录页
|-NotFound/index.jsx # 404页
内容如下:
在 pages 目录中创建两个页面:Login、Layout
src/pages/Layout/index.js
const Layout = () => {
return <div>Layout</div>
}
export default Layout
src/pages/Login/index.js
const Login = () => {
return <div>登录页面</div>
}
export default Login
1.1.1导入路由组件配置路由
在 App 组件中:
- 导入路由组件
- 导入页面组件
- 配置路由规则
import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import Login from './pages/Login'
import Layout from './pages/Layout'
import NotFound from './pages/NotFound'
export default function App() {
return (
<Router>
<div className="app">
<Switch>
<Route path="/login" component={Login}></Route>
<Route path="/layout" component={Layout}></Route>
{/* 增加一个404 */}
<Route component={NotFound}></Route>
</Switch>
</div>
</Router>
)
}
组件库 - antd
目标
了解antd的基本使用,能用 Button 组件渲染按钮
antd
antd
是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。
安装
npm i antd
使用步骤
在 index.js 中导入 antd 的样式文件
// 1 在 index.js 中导入 antd 的样式文件
import 'antd/dist/antd.css'
在其他组件中引入使用
// 2 在 Login 页面组件中,使用 antd 的 Button 组件
import { Button } from 'antd'
const Login = () => (
<div>
<Button type="primary">Button</Button>
</div>
)
vscode识别@路径并给出路径提示
目标
能够让vscode识别@路径并给出路径提示
步骤
- 在项目根目录创建
jsconfig.json
配置文件 - 在配置文件中添加以下配置
jsconfig.json 中:
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
}
}
小结
VSCode 会自动读取 jsconfig.json
中的配置,让 vscode 知道 @ 就是 src 目录
用craco来配置路径别名
目标
配置@路径别名,让脚手架工具能识别@
背景
CRA(create-react-app) 将所有工程化配置,都隐藏在了 react-scripts
包中,所以,项目中看不到任何配置信息或者是配置文件。
如果要修改 CRA 的默认配置,有以下几种方案:
- 【推荐】通过第三方库来修改,比如,
@craco/craco
- 通过执行
yarn eject
命令,释放react-scripts
中的所有配置到项目中(注意:该操作不可逆!!!)
craco是什么
Create React App Configuration Override, an easy and comprehensible configuration layer for create-react-app
craco是用来对create-react-app进行自定义配置的工具。
- 安装包。
npm i -D @craco/craco
- 在项目根目录下,创建配置文件:
craco.config.js
。在配置文件中就可以做自定义的修改了。
craco.config.js
配置路径别名
const path = require('path')
module.exports = {
webpack: {
alias: {
'@': path.join(__dirname, 'src')
}
}
}
3.修改 package.json
中的脚本命令
package.json 中:
// 将 start/build/test 三个命令修改为 craco 方式
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
4.在代码中,就可以通过 @
来表示 src 目录的绝对路径
5.重启项目,让配置生效
封装axios 的工具函数
目标
安装axios并做基本配置
安装axios
npm i axios
配置基地址;
配置基本的请求拦截器和响应拦截器
import axios from 'axios'
const instance = axios.create({
baseURL: 'http://geek.itheima.net/v1_0/',
timeout: 5000,
})
// 请求拦截器
instance.interceptors.request.use(
function (config) {
return config
},
function (error) {
// 如果没有网络,
if(!err.response) {
alert('网络失败')
return Promise.reject(err)
}
return Promise.reject(error)
}
)
// 响应拦截器
instance.interceptors.response.use(
function (response) {
return response.data
},
function (error) {
return Promise.reject(error)
}
)
export default instance
测试
任意找个地方写下button和点击事件,在回调中使用
import request from 'utils/request.js'
test = () => {
request({url: '/channels'})
}
sass的使用
在react脚手架中已经有了sass的配置,因此只需要安装sass的依赖包,就可以直接使用sass了
- 安装sass依赖包
npm i sass -D
把index.css
改成index.scss
- 导入
index.scss
文件
注意:如果使用了scss,scss中使用图片的绝对路径的时候需要加上~
background-image: url(~assets/login.png);
css-样式污染
目标
了解样式污染的现象及原因;
了解css in js解决方案
问题引入
在Login组件的index.scss
中添加样式
.root {font-size: 100px;}
给Login和Layout组件的根元素都添加.root这个类
发现在Layout
组件中的样式也跟着发生了改变。
原因
在配置路由时,Layout和 Login组件都被导入到项目中,那么组件的样式也就被导入到项目中了。如果组件之间选择器重复,那么一个组件中的样式就会在另一个组件中也生效,从而造成组件之间样式相互覆盖的问题。
解决方案
- 手动处理 (起不同的类名)
CSS IN JS
: 以js的方式来处理css 。思想是让css有局部作用域全局作用域这样的区分
CSS IN JS
- CSS IN JS:是使用 JavaScript 编写 CSS 的统称,用来解决 CSS 样式冲突、覆盖等问题
- CSS IN JS 的具体实现有 50 多种,比如:CSS Modules、styled-components 等
- 推荐使用:CSS Modules (React脚手架已集成,可直接使用)
css modules-基本使用
目标
掌握css modules的基本使用。
步骤
- 改样式文件名。从
xx.scss -> xx.module.scss
(React脚手架中的约定,与普通 CSS 作区分) - 引入使用。
- 组件中导入该样式文件(注意语法)
import styles from './index.module.scss'
2. 通过 styles 对象访问对象中的样式名来设置样式
<div className={styles.css类名}></div>
示例
原来
- 定义样式 index.css
.root {font-size: 100px;}
- 使用样式
import 'index.css'
<div className="root">div的内容</div>
现在
修改文件名: index.css ----> index.module.css。内部不变
使用样式
import styles from './index.module.css'
<div className={styles.root}>div的内容</div>
原理
CSS Modules 通过自动给 CSS 类名补足类名,保证类名的唯一性,从而避免样式冲突的问题 。
// Login.jsx
import styles from './index.module.css'
console.log(styles)
css module的注意点
类名最好使用驼峰命名,因为最终类名会生成styles
的一个属性
.tabBar {} ---> styles.tabBar
如果使用中划线的命名,需要使用[]语法
.tab-bar {} ---> styles['tab-bar']
CssModules-维持类名
目标
掌握:global关键字的用法,能用它来维持原类名
在xxx.module.scss中,如果希望维持类名,可以使用格式:
:global(.类名)
示例
/*这样css modules就不会修改掉类名.a了。等价于写在 index.css中 */
:global(.a) { }
/* 这样css modules就不会修改掉类名.a了, 但是 .aa还是会被修改 */
.aa :golbal(.a) { }
应用
覆盖第三方组件的样式
:global(.ant-btn) {
color: red !important;
}
css modules-最佳实践
- 每个组件的根节点使用 CSSModules 形式的类名( 根元素的类名:
root
) - 其他所有的子节点,都使用普通的 CSS 类名 :global
index.module.scss
// index.module.scss
.root {
display: 'block';
position: 'absolute';
// 此处,使用 global 包裹其他子节点的类名。此时,这些类名就不会被处理,在 JSX 中使用时,就可以用字符串形式的类名
// 如果不加 :global ,所有类名就必须添加 styles.title 才可以
:global {
.title {
.text {
}
span {
}
}
.login-form { ... }
}
}
组件
import styles from './index.module.scss'
const 组件 = () => {
return (
{/* (1) 根节点使用 CSSModules 形式的类名( 根元素的类名: `root` )*/}
<div className={styles.root}>
{/* (2) 所有子节点,都使用普通的 CSS 类名*/}
<h1 className="title">
<span className="text">登录</span>
<span>登录</span>
</h1>
<form className="login-form"></form>
</div>
)
}
引入ESlint
目标
安装并配置eslint,配置vscode快捷键,ctrl + s 保存格式化。
具体如何可以在新的项目上安装并使用,直到正常运行,可以观看我的另一篇博客