一、创建项目
注意: 创建项目的时候,记得暴露配置文件 ( npm run eject
或者 yarn run eject
)
因为暴露配置的文件的操作不可逆
,之前没有提及git的话,可能会报错,还需重新git add . ; git commit -m "初始化(备注)"
)
yarn global add create-react-app /* 本地全局安装 react 脚手架 */
create-react-app my-react-demo /* 创建一个名为 my-react-demo 的React项目 */
cd my-react-demo /* 进入项目根目录 */
yarn run eject /* 放出配置信息; //新版本的脚手架把配置文件等都以依赖的形式放到 node_modules 中了, eject 一下,把配置信息释放出来 */
yarn start /* 运行项目 */
① 全局安装React
脚手架,成功:
② 创建一个名为 my-react-demo
的React
项目成功:
③: 进入项目根目录,并运行 yarn run eject
成功:
对比: 未执行 yarn run eject
命令的项目和执行了 yarn run eject
的项目结构对比:(多了配置文件,访问效果相同
)
在项目目录的scripts
文件夹下的start.js
中可以修改端口号 ( 默认端口是 3000
)
运行效果如下:
参考:https://www.cnblogs.com/pengfei-nie/p/10443310.html#a1
二、精简项目
1. 删除文件( 删除一般项目中用不到的文件,最简化项目 )
删除上述文件后,项目目录结构如下:
(public
下的favicon.ico
是网页图标;public
下的index.html
是HTML
模板;src
下的index.js
文件是项目的入口文件;src
下的App.js
是项目主模块)
2. 简化代码(删除这些文件和代码后,相应的文件引用已不存在,项目报错,需修改代码)
① src
下的index.js
修改如下:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
② src
下的APP.js
修改如下:
import React from 'react';
function App() {
return (
<div className="App">
<h1>App page</h1>
</div>
);
}
export default App;
③ public
下的index.html
修改如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
运行效果如下:
3. 使用Fragment去掉组件外层标签
react
要求每个组件返回 JSX
时,的最外层必须是由一个标签包裹,且不能存在并列的标签。
① 例如,在src/App.js
中,如果是这样就会报错:
// 以下代码将会报错,最外层不能存在并列的标签。
import React from 'react';
function App() {
return (
<div className="App">
<h1>This is React App1</h1>
</div>
<div className="App">
<h1>This is React App2</h1>
</div>
);
}
export default App;
② 正解: 最外层必须是由一个标签包裹,所以这里,id
为app_outside
这个div
标签是必须的,但是,这样在渲染的时候,DOM
结构将更深一层
import React from 'react';
function App() {
return (
<div id="app_outside">
<div className="App">
<h1>This is React App1</h1>
</div>
<div className="App">
<h1>This is React App2</h1>
</div>
</div>
);
}
export default App;
div
作为最外层的时候,渲染出的DOM
结构:
③ 有时,我们如果确实需要两个DOM 并列的DOM 结构,且并不想再添加一个父级标签,这个时候,我们就可以使用Fragment
作为最外层。此时渲染的结构中:
import React, { Fragment } from 'react'
function App() {
return (
<Fragment>
<div className="App">
<h1>This is React App1</h1>
</div>
<div className="App">
<h1>This is React App2</h1>
</div>
</Fragment>
);
}
export default App;
Fragment
作为最外层的时候,渲染出的DOM
结构如下:
博客参考:https://juejin.im/post/5e36b72ee51d45307546b29c#heading-14
三、完善目录结构
1. 项目的目录结构,可按照个人开发习惯和项目实际来定,如:
assets 静态资源文件夹,存放 字体、图片、css样式 等
components 公共组件文件夹,放公共组件
layouts 布局文件夹, 项目布局
utils 公共函数文件夹 存放公共函数、一些插件的启动配置函数
pages 具体的功能模块, 存放项目的实际页面
services 接口文件夹 存放所有请求
store 装redux的
如在src
下新建了assets
文件夹:
四、安装相应的插件,并使用
1. 安装Sass
(React
支持Sass/Less/Stylus
,习惯用sass
)eject
后,package.json
以及webpack.config.js
里有了sass
相关代码,但要正确使用Sass/Scss
,还需安装node-sass
。
1) 安装
yarn add node-sass
安装完成便可在项目中直接使用sass
的语法 (记得 把 .css
的后缀名改成 .scss
)
2) 使用sass
如:在项目的src
下新增了assets
文件夹及其子文件夹:
global.scss
( 全局公用样式 )
body{
background: lightyellow;
h1{
color:rgb(247, 6, 6)
}
}
在src
下的index.js
中引入了global.scss
:
import "./assets/style/global.scss" ; /* + 引入全局公用样式global.scss文件 */
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; /* APP 组件 是使用Fragment 作为最外层那个文件,未做任何改变 。*/
ReactDOM.render(<App />, document.getElementById('root'));
效果如图:
2. 安装路由插件:react-router-dom
1)安装:
yarn add react-router-dom
2)使用使用react-router-dom
header / header.scss
:
.header{
background: #fff;
.nav{
display: inline-block;
width: 100px;
text-decoration: none;
text-align: center;
background: #dedede;
color: #333;
padding: 12px;
}
.nav_active{
background: tomato;
color: #fff;
}
}
header / index.js
:
注意:
NavLink
是导航链接,activeClassName
是元素处于活动状态时提供的类;此处的,exact
是必须的,为true
,表示path
完全匹配时,才会应用活动的样式;
import React,{Component} from 'react';
import {NavLink} from 'react-router-dom'
import "./header.scss";
class Header extends Component{
render(){
return (
<div className="header">
<NavLink exact to="/" activeClassName="nav_active" className="nav">Home</NavLink>
<NavLink to="/login" className="nav" activeClassName="nav_active" >Login</NavLink>
</div>
)
}
}
export default Header;
home / index.js
:
import React, {Component,Fragment} from 'react';
import Header from '../../components/header'; /* 引入header文件夹下的index.js文件中定义的Header组件 */
class Home extends Component{
render(){
return (
<Fragment>
<Header></Header>
<h2>Home page</h2>
<p>This is home page.</p>
</Fragment>
)
}
}
export default Home;
login / index.js
:
import React,{Component, Fragment} from 'react';
import Header from '../../components/header'; /* 引入header文件夹下的index.js文件中定义的Header组件 */
class Login extends Component{
render(){
return (
<Fragment>
<Header></Header>
<h2>Login page</h2>
<p>This is login page.</p>
</Fragment>
)
}
}
export default Login;
src / App.js
:
import React, { Fragment } from 'react'
import {HashRouter,Switch,Route,Redirect } from 'react-router-dom'
import Home from './pages/home';
import Login from './pages/login';
function App() {
return (
<Fragment>
<HashRouter>
<Switch>
<Route exact path="/" component={Home}></Route>
<Route path="/login" component={Login}></Route>
<Route path="/home" component={Home}></Route>
<Redirect to="/home"></Redirect>
</Switch>
</HashRouter>
</Fragment>
);
}
export default App;
注意:
1. App.js
引入了Home
和Login
两个页面级组件。然后使用react-router-dom
分别设置了路径。
2. import
的机制是默认寻找index.js
,所以每个组件的主文件名设为index.js
,在引用的时候就可以省略文件名
3. 注意 <Route>
的属性:
path 表示路径。
component 表示绑定的组件。
exact 表示是否精确匹配,如果没有设置exact,那只要path中含有 ' / ',路由就会成功,就会匹配到Home页,那'/login'也会匹配到Home页
<Redirect>表示以上都没有匹配成功的,会默认跳转的路由。
src
下的index.js
:
import "./assets/style/global.scss" ; /* + 引入全局公用样式global.scss文件 */
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
效果如图:
react-router-dom
更多信息 ,参考官网:https://reacttraining.com/react-router/web/guides/quick-start
五、React项目中 使用antd( Ant Design)
实现antd在react项目中的按需引入
1. 安装antd
yarn add antd
2. 引入并使用:
- React中使用Ant Design 组件,Form表单的使用示例:
篇一中的各文件和结构不做任何变化,修改login/index.js
文件如下:
login / index.js :
import React,{Component, Fragment} from 'react';
import Header from '../../components/header';
import 'antd/dist/antd.css'; /* 1. 引入antd的样式文件 */
import {Form,Input,Button} from 'antd'; /* 2. 引入所需的antd组件 */
import "./login.scss" /* 引入当前文件夹下的login.scss样式文件 */
const layout ={
labelCol:{span:3},
wrapperCol:{offset:1,span:10}
}
const onFinish=values=>{
console.log(values) // 打印结果如:{userName: "na", pwd: "111111"}
}
const onFinishFailed=errorInfo=>{
console.log('Failed:',errorInfo);
}
const rules={
userName:[{required:true,message:'请输入用户名'}],
pwd:[{required:true,message:'请输入密码'}]
}
class Login extends Component{
render(){
return (
<Fragment>
<Header></Header>
<h2>Login page</h2>
<p>This is login page.</p>
<div className="login_outside">
<Form
{...layout}
name="basic"
initialValues={{remember:true}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item label="用户名:" name="userName" rules={rules.userName}>
<Input />
</Form.Item>
<Form.Item label="密码:" name="pwd" rules={rules.pwd}>
<Input.Password/>
</Form.Item>
<Form.Item >
<Button className="login_btn" type="primary" danger htmlType="submit">登录</Button>
</Form.Item>
</Form>
</div>
</Fragment>
)
}
}
export default Login;
login/login.scss
:
.login_outside{ width: 600px; }
.login_btn{width:200px;margin-left: 100px; }
src / index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "./assets/style/global.scss"
ReactDOM.render(<App />, document.getElementById('root'));
效果及项目目录结构如图:
github项目地址:
https://github.com/ddx2019/my-react-demo
( 项目中新加了swiper插件 )