前言
快速搭建我们的管理系统,这里记录一下自己的一些学习经验,希望能为小伙伴们带来方便,话不多说,开始我们的正文。
create-react-app脚手架生成项目
使用yarn安装
yarn create react-app my-demo --typescript
使用npm安装(npx 来自 npm 5.2+ 或更高版本)
npx create-react-app my-demo --typescript
安装完成之后
cd my-demo
yarn start
or
npm start
此时浏览器会访问 http://localhost:3000/ ,看到 Learn React 的界面就算成功了。
此时我们删除掉多余文件,保留最简单文件。替换index和app的内容。
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
app.tsx
import React from 'react';
function App() {
return (
<div className="App">
welcome to my-demo
</div>
);
}
export default App;
最后目录如下:
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.tsx
│ ├── index.tsx
│ └── react-app-env.d.ts
├── package.json
├── README.md
├── tsconfig.json
└── yarn.lock
安装antd
因为官方脚手架把webpack封装在内部,如果我们想要自己配置webpack,可以使用yarn eject命令暴露相关配置,这里我选择暴露webpack。(注:此命令不可逆转)
yarn eject
or
npm run eject
这时我们可能会在执行命令时候报错,原因是git没有提交相应操作代码。
第一步
git add.
第二步
git commit -m "init"
接下来再重新执行eject命令就好了。
安装antd(下面命令都用yarn做演示)
yarn add antd
使用 babel-plugin-import 来进行按需加载
yarn add babel-plugin-import
修改webpack.config.js文件大概374行,增加如下代码
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}],
增加less配置
yarn add less less-loader
修改webpack.config.js 52行新增
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
在sass-loader配置后新增
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'less-loader'
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'less-loader'
),
},
安装react-router-dom
yarn add react-router-dom @types/react-router-dom
接下来我们修改一下文件目录并且添加相应的文件
├── config
│ ├── env.js
│ ├── getHttpsConfig.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── public
│ ├── favicon.ico
│ └── index.html
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.tsx
│ ├── components
│ ├── index.tsx
│ ├── pages
│ │ ├── home
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ └── login
│ │ ├── index.less
│ │ └── index.tsx
│ ├── react-app-env.d.ts
│ └── router
│ └── main.tsx
├── package.json
├── README.md
├── tsconfig.json
└── yarn.lock
对应有修改的文件
app.tsx
import React from 'react';
import { HashRouter } from "react-router-dom";
import Main from './router/main'
function App() {
return (
<HashRouter>
<Main />
</HashRouter>
);
}
export default App;
main.tsx
import React from "react";
import { Switch, Route, Redirect, Link, withRouter } from "react-router-dom";
import Home from '../pages/home';
import Login from '../pages/login';
export default () => (
<Switch>
<Route path='/home' component={Home} />
<Route path='/login' component={Login} />
<Redirect to='/login' />
</Switch>
)
home/index.tsx
import React, { Component } from 'react';
import {Button} from 'antd';
interface Iprops{
history:any
}
class Home extends Component<Iprops,any> {
render() {
return (
<div>
<h1>我是主页</h1>
<Button type='primary' onClick={()=>this.props.history.push('/login')}>跳转到登录页</Button>
</div>
);
}
}
export default Home;
login/index.tsx
import React, { Component } from 'react';
import {Button} from 'antd';
interface Iprops{
history:any
}
class Login extends Component<Iprops,any> {
render() {
return (
<div>
<h1>我是登录页</h1>
<Button type='primary' onClick={()=>this.props.history.push('/home')}>跳转到主页</Button>
</div>
);
}
}
export default Login;
到此为止我们的路由就已经可以正常跳转了
最后加入redux
yarn add redux react-redux @types/react-redux
具体redux使用方法请自行查找相关资料,本文只给出具体列子不做详细讲解
下面就拿home页面做一个todolist演示,最终文件如下:
文件目录:
├── config
│ ├── env.js
│ ├── getHttpsConfig.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── public
│ ├── favicon.ico
│ └── index.html
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.tsx
│ ├── components
│ ├── index.tsx
│ ├── pages
│ │ ├── home
│ │ │ ├── index.less
│ │ │ ├── index.tsx
│ │ │ └── store
│ │ │ ├── action.tsx
│ │ │ └── reducer.tsx
│ │ └── login
│ │ ├── index.less
│ │ └── index.tsx
│ ├── react-app-env.d.ts
│ ├── router
│ │ └── main.tsx
│ └── store
│ ├── index.tsx
│ └── reducer.tsx
├── package.json
├── README.md
├── tsconfig.json
└── yarn.lock
store/index.tsx
import {createStore} from 'redux'
import reducer from './reducer'
const store=createStore(reducer)
export default store
store/reducer.tsx
import {combineReducers} from 'redux'
import HomeReducer from '../pages/home/store/reducer';
const reducer=combineReducers({
Home:HomeReducer
})
export default reducer
home/index.tsx
import React, { Component } from 'react';
import { Button, Input, Row, Col, Divider, List } from 'antd';
import { connect } from 'react-redux'
import { changeData } from './store/action'
import './index.less'
const { Search } = Input;
interface Iprops {
history: any
homeState: Array<any>
changeData: Function
}
class Home extends Component<Iprops, any> {
constructor(props: any) {
super(props)
this.state = {
value: ''
}
}
private handleSearch = (value: any) => {
const { changeData } = this.props;
changeData({ action: 'ADD', value })
this.setState({ value: '' })
}
private handeChange = (e: any) => {
this.setState({ value: e.target.value })
}
private deleteItem = (index: number) => {
const { changeData } = this.props;
changeData({ action: 'DEL', value: index })
}
render() {
const { homeState } = this.props;
return (
<div>
<h1>我是主页</h1>
<Button type='primary' onClick={() => this.props.history.push('/login')}>跳转到登录页</Button>
<Divider orientation="center">todolist演示</Divider>
<Row justify='center' gutter={[16, 16]}>
<Col span={10} >
<Search
value={this.state.value}
placeholder="请输入内容"
enterButton="确定"
size="large"
onSearch={this.handleSearch}
onChange={this.handeChange}
/>
<List
bordered
dataSource={homeState}
renderItem={(item: any, index: number) => (
<List.Item>
<div className='content'>
<span>{item}</span>
<span className='del' onClick={this.deleteItem.bind(this, index)}>删除</span>
</div>
</List.Item>
)}
/>
</Col>
</Row>
</div>
);
}
}
// 把store中的数据映射到组件的props
const mapStateToProps = (state: any) => ({
homeState: state.Home
})
// 把store的Dispatch映射到组件的props
const mapDispatchToProps = (dispath: any) => ({
changeData: (data: any) => dispath(changeData(data))
})
export default connect(mapStateToProps, mapDispatchToProps)(Home);
home/index.less
.content{
width: 100%;
display: flex;
justify-content: space-between;
.del{
cursor: pointer;
color: red;
}
}
home/store/action.tsx
export const ADD_DATA='ADD_DATA'; // 增加数据
export const DEL_DATA='DEL_DATA'; // 删除数据
// 改变state的action
export const changeData=(data:any)=>{
if(data.action==='ADD'){
return{
type:ADD_DATA,
value:data.value
}
}else{
return{
type:DEL_DATA,
value:data.value
}
}
}
home/store/reducer.tsx
let defaultState:Array<any>=[]
const todolist=(state:Array<any>=defaultState,action:any)=>{
const newState=[...state]
switch(action.type){
case 'ADD_DATA':
newState.push(action.value)
return newState
case 'DEL_DATA':
newState.splice(action.value,1)
return newState
default:return state
}
}
export default todolist
App.tsx
import React from 'react';
import { HashRouter } from "react-router-dom";
import Main from './router/main';
import { Provider } from 'react-redux';
import store from './store';
function App() {
return (
<Provider store={store}>
<HashRouter>
<Main />
</HashRouter>
</Provider>
);
}
export default App;
到此完毕,以上就是整个项目的完整的代码了,希望能对各位有所帮助。