最近公司在做框架选型,有前端朋友推荐了这一套组合拳,打算写个demo练练手,顺便踩踩坑。项目初始参考antd的官方文档 在typescript中使用antd
项目地址
项目地址 : https://github.com/NeptunerLynn/react_hook_ts
参考文档
一. 环境配置
1. 创建项目
npx create-react-app ts_hook_proj --typescript
然后把配置项暴露出来(不可逆操作)
npm run eject
启动项目
npm run start
默认启动地址是 http://localhost:3000/
2. 引入antd
yarn add antd
在app.tsx中引入antd
import { Button } from 'antd';
在app.css中引入css样式
@import '~antd/dist/antd.css';
3.配置主题色
安装craco对create-react-app进行配置
yarn add @craco/craco
cnpm i react-scripts -S
将package.json中的配置修改为:
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
},
引入
yarn add craco-less
在项目根目录新建文件craco.config.js,并添加代码:
const CracoLessPlugin = require('craco-less');
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: { '@primary-color': '#1DA57A' },
javascriptEnabled: true,
},
},
},
},
],
};
然后将App.tsx中的样式引用修改为
import './App.less';
并新增文件App.less
@import '~antd/dist/antd.less';
到这里,主题已经成功的配置好了
在App.tsx里试着使用一下
import React, { FC } from 'react';
import { Button } from 'antd';
import './App.less';
const App: FC = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
);
export default App;
可以看到,在浏览器中已经成功显示了:
二. 目录梳理
在开发项目之前,个人习惯是进行目录的整理,为后续的开发提供框架
先大致的整理一下目录结构
我们开发的代码主要存放在src中。
三. 添加组件
安装react-router
yarn add react-router @types/react-router --dev
yarn add react-router-dom @types/react-router-dom --dev
安装redux
yarn add redux --dev
然后开始正儿八经的开发代码了:
新增路由router/index.tsx
先跳转登录页面,登录成功之后进入主页,另有进入注册页面的入口:
import * as React from 'react';
import { HashRouter as Router, Redirect, Route, Switch } from 'react-router-dom';
import HomePage from '../components/views/HomePage';
import LoginPage from '../components/views/LoginPage';
import RegisterPage from '../components/views/RegisterPage';
const basename = '/';
const RoutersConfig = () => {
return (
<Router basename={basename}>
<Switch>
<Route path='/login' exact={true} component={LoginPage} />
<Route path='/home' component={HomePage} />
<Route path='/register' component={RegisterPage} />
<Redirect to='/login' />
</Switch>
</Router>
);
}
export default RoutersConfig;
在主组件App.tsx中引入router
import * as React from 'react';
import RoutersConfig from './routers';
import './App.less'
class App extends React.Component {
public render() {
return (
<RoutersConfig />
);
}
}
export default App;
然后写登录-views/LoginPage.tsx(不得不说,默默踩了一堆antd3到antd4的坑):
import { Button, Checkbox, Form, Input, message } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
// import { FormComponentProps } from 'antd/lib/form';
import * as React from 'react';
import { RouteComponentProps } from 'react-router-dom';
import '../../assets/less/login.less';
interface LoginParam {
username: string;
password: string;
remember: boolean;
}
interface LoginFormProps extends RouteComponentProps {}
class LoginPage extends React.Component<LoginFormProps, LoginParam> {
readonly state: Readonly<LoginParam> = {
username: '',
password: '',
remember: true,
}
constructor(props: LoginFormProps) {
super(props);
}
onFinish = values => {
console.log(this.props)
console.log('Success:', values);
this.props.history.push('/home');
}
onFinishFailed = errorInfo => {
console.log('Failed:', errorInfo);
}
onRegister = () => {
this.props.history.push('/register');
}
render() {
return (
<div id="loginContent">
<div className="login-card">
<div className="login-card-title">欢 迎 登 录</div>
<Form
name="basic"
initialValues={{ remember: true }}
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
>
<Form.Item
name="username"
rules={[{ required: true, message: '请输入账号!' }]}
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="账号" />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: '请输入密码!' }]}
>
<Input.Password prefix={<LockOutlined className="site-form-item-icon" />} placeholder="密码"/>
</Form.Item>
<Form.Item>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox>记住密码</Checkbox>
</Form.Item>
<a className="login-form-forgot" href="#!" onClick={this.onRegister}>
没有账号?先注册吧!
</a>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" block>
登录
</Button>
</Form.Item>
</Form>
</div>
</div>
);
}
}
export default LoginPage;
为登录添加样式:
#loginContent{
background-color: @primary-color;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.login-card{
background: #fff;
width: 400px;;
border-radius: 10px;
box-shadow: 0 0 10 #ccc;
padding: 20px 50px;
.login-card-title{
text-align: center;
font-size: 18px;
margin-bottom: 16px;
}
.login-form-forgot {
float: right;
}
}
}
homePage.tsx
import * as React from 'react';
const HomePage = () => {
return (
<div>Welcome to React!</div>
)
}
export default HomePage;
现在已经能够成功跳转到主页了:
关于注册页面,还有登录的请求接口添加,token状态等等未完待续o( ̄︶ ̄)o~