一、創建項目
注意: 創建項目的時候,記得暴露配置文件 ( 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插件 )