01-基本结构
目标:能够利用模板代码搭建基础布局步骤:
- 在 Login/index.js 中创建登录页面基本结构
- 在 Login 目录中创建 index.scss 文件,指定组件样式
- 将 logo.png 和 login.png 拷贝到 assets 目录中
核心代码:
pages/Login/index.js 中:
import logo from ‘../../assets/logo.png’
import ‘./index.scss’
const Login = () => {
return (
{/ 登录表单 /}
)
}
export default Login
pages/Login/index.scss 中:
.login {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background:#f0f2f5 center/cover url(https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg);
.login-logo {
width: 200px;
height: 60px;
display: block;
margin: 0 auto 40px;
}
.login-container {
width: 320px;
height: 360px;
position: absolute;
left: 50%;
top: 42%;
transform: translate(-50%, -50%);
}
}
02-创建表单
目标:能够使用 antd 的 Form 组件创建登录表单步骤:
- 打开 antd Form 组件文档
- 找到代码演示的第一个示例(基本使用),点击 < >(显示代码),并拷贝代码到组件中
- 分析 Form 组件基本结构
- 调整 Form 组件结构和样式
核心代码:
pages/Login/index.js 中:
import { Form, Input, Button, Checkbox } from ‘antd’
import { UserOutlined, LockOutlined } from “@ant-design/icons”;
const Login = () => {
return (
} placeholder=”请输入手机号” />
} placeholder=”请输入验证码” />
)
}
03-表单校验
目标:能够为手机号和密码添加表单校验
分析说明:
- Form 表单校验的默认触发时机是:onChange
- 如果要修改触发时机,就必须先修改其所在 Form.Item 或 Form 的 validateTrigger 属性值
- 如果 Form.Item 包裹的表单项的值不是 value 的话,需要通过 valuePropName 来指定其值
- 比如,如果在 Form.Item 中使用 Checkbox,就需要将 valuePropName 设置为 checked,因为复选框操作的是选中值
步骤:
- 为 Form 组件添加 validateTrigger 属性,指定校验触发时机的集合
- 为 Form.Item 组件添加 name 属性,这样表单校验才会生效
- 为 Form.Item 组件添加 rules 属性,用来添加表单校验
核心代码:
pages/Login/index.js 中:
rules={[
{ required: true, message: “请输入手机号” },
{
pattern: /^1[3-9]\d{9}$/,
message: “手机格式不正确”,
},
]}
>
} placeholder=”请输入手机号”>
rules={[
{ required: true, message: “请输入验证码” },
{ len: 6, message: “验证码6个字符串” },
]}
>
} placeholder=”请输入验证码”>
valuePropName=”checked”
>
总结:
- 表单校验时 Form.Item 可以没有 name 属性吗? 不可以
- 什么情况下需要添加 Form.Item 的 valuePropName 属性?
- required 不支持布尔值的校验,需要通过vaildator 添加自定义校验函数
- 函数默认两个参数 rule 和 value ,第二个就是表单元素的值
- 自动来为value添加校验逻辑,成功调用 Promise.resolve()
- 失败调用 Promise.reject(new Error(‘错误提示’))
核心代码:
valuePropName=”checked”
rules={[
{
validator: (_, value) => {
if (value === true) return Promise.resolve();
else return Promise.reject(new Error(“请勾选我已阅读并同意”));
},
},
]}
>
05-获取登录表单值
目标:能够拿到登录表单中的手机号码和验证码
分析说明:
Form 组件提供了 onFinish 属性来进行表单提交
步骤:
- 给 Button 添加 htmlType=”submit” 可触发 Form 组件的提交事件 onFinish
- 为 Form 组件添加 onFinish 属性,该事件会在点击登录按钮时触发
- 创建 onFinish 函数,通过函数参数 values 拿到表单值
- 为了方便,为 Form 组件添加 initialValues 属性,来初始化表单值
核心代码:
pages/Login/index.js 中:
const onFinish = values => {
console.log(values)
}
总结:
- 如何点击按钮触发Form的提交事件?
- 如何获取到 Form 表单中的值?
-
06-配置Redux
目标:能够完成Redux的基础配置
步骤: 安装 redux 相关的包:yarn add redux react-redux redux-thunk redux-devtools-extension axios
- 在 store 目录中分别创建:actions 和 reducers 文件夹、index.js 文件
- 在 store/index.js 中,创建 store 并导出
- 创建 reducers/index.js 文件,创建 rootReducer 并导出
- 创建 reducers/user.js 文件,创建基础 user reducer 并导出
- 在 src/index.js 中为 React 组件接入 Redux
核心代码:
store 目录结构:
/store
/actions
/reducers
user.js
index.js
index.js
store/index.js 中:
import { createStore, applyMiddleware } from ‘redux’
import rootReducer from ‘./reducers’
import thunk from ‘redux-thunk’
import { composeWithDevTools } from ‘redux-devtools-extension’
const middlewares = composeWithDevTools(applyMiddleware(thunk))
const store = createStore(rootReducer, middlewares)
export default store
store/reducers/index.js 中:
import { combineReducers } from ‘redux’
import user from ‘./user’
const rootReducer = combineReducers({
user
})
export default rootReducer
store/reducers/user.js 中:
// 登录功能,只需要存储 token 即可,所以,状态默认值为:’’
const initialState = {
token: ‘’
}
const user = (state = initialState, action) => {
return state
}
export default user
src/index.js 中:
import { Provider } from ‘react-redux’
import store from ‘./store’
ReactDOM.render(
document.querSelector(‘#root’)
)
07-Redux登录
目标:能够通过 Redux 实现登录功能
分析说明:
- 登录时,会将 token 保存到本地缓存中,为了方便后续操作,可以在 Redux 状态中也保存一份。
- 但如果不处理,刷新页面时,Redux 中存储的 token 就没有了。
- 所以,为了能够在刷新页面时,也能让 Redux 拿到 token 值
步骤:
- 在 Login 组件中分发登录的异步 action
- 创建 actions/user.js 文件,实现登录逻辑
- 创建 actions/index.js 文件,统一导出 user 中的函数,简化导入
- 在 reducers/user.js 中,处理登录相关状态,从本地缓存初始化 Redux 的 token 状态
- 登录成功后,跳转到首页
核心代码:
pages/Login/index.js 中:
import { message } from ‘antd’
import { useDispatch } from ‘react-redux’
import { useHistory } from ‘react-router’
import { login } from ‘@/store/actions’
const Login = () => {
const dispatch = useDispatch()
const history = useHistory()
const onFinish = async values => {
const { mobile, code } = values
try {
await dispatch(login(mobile, code))
history.replace(‘/home’)
} catch (e) {
message.error(e.response?.data?.message || ‘登录失败’)
}
}
// …