在src/pages/Profile/index.js中添加如下代码:
render() {
return (
{/* 个人信息 */}
{nickname || '游客'}
{/* 登录后展示: */}
{isLogin ? (
<>
退出
编辑个人资料
>
) : (
)}
{/* 未登录展示: */}
{/* 九宫格菜单 */}
item.to ? (
{item.name}
) : (
{item.name}
)
}
/>
{/* 加入我们 */}
)
}
实现步骤:
1、在state中添加两个状态:isLogin(是否登录)和userInfo(用户信息)
2、从utils中导入isAuth(登录状态)、getToken(获取token)
3、创建方法getUserInfo,用户来获取个人资料
4、在方法中,通过isLogin判断用户是否登录
5、如果没有登录,则不发送请求,渲染未登录信息
6、如果已登录,就根据接口发送请求,获取用户个人资料
7、渲染个人资料数据
代码示例:
在src/pages/Profile/index.js中添加如下代码:
import { BASE_URL, isAuth, getToken, API } from '../../utils'
export default class Profile extends Component {
state = {
// 是否登录
isLogin: isAuth(),
// 用户信息
userInfo: {
avatar: '',
nickname: ''
}
}
// 注意:不要忘了在进入页面时调用方法 !
componentDidMount() {
this.getUserInfo()
}
async getUserInfo() {
if (!this.state.isLogin) {
// 未登录
return
}
// 发送请求,获取个人资料
const res = await API.get('/user', {
headers: {
authorization: getToken()
}
})
if (res.data.status === 200) {
const { avatar, nickname } = res.data.body
this.setState({
userInfo: {
avatar: BASE_URL + avatar,
nickname
}
})
}
}
render() {
const { history } = this.props
const {
isLogin,
userInfo: { avatar, nickname }
} = this.state
return (
{/* 个人信息 */}
{nickname || '游客'}
{/* 登录后展示: */}
{isLogin ? (
<>
退出
编辑个人资料
>
) : (
)}
{/* 未登录展示: */}
{/* 九宫格菜单 */}
item.to ? (
{item.name}
) : (
{item.name}
)
}
/>
{/* 加入我们 */}
)
}
}
实现步骤:
1、点击退出按钮,弹出对话框,提示是否确定退出
2、给退出按钮绑定点击事件,创建方法logout作为事件处理函数
3、导入Modal对话框组件(弹出模态框)
4、在方法中,拷贝Modal组件文档中确认对话框的示例代码
5、修改对话框的文字提示
6、在退出按钮的事件处理程序中,先调用退出接口(让服务器端退出),再移除本地token(本地退出)
7、把登录状态isLogin设置为false
8、清空用户状态对象
代码示例:
在src/pages/Profile/index.js中添加如下代码:
import {..., Modal } from 'antd-mobile'
const alert = Modal.alert
// 退出
logout = () => {
alert('提示', '是否确定退出?', [
{ text: '取消' },
{
text: '退出',
onPress: async () => {
// 调用退出接口
await API.post('/user/logout', null, {
headers: {
authorization: getToken()
}
})
// 移除本地token
removeToken()
// 处理状态
this.setState({
isLogin: false,
userInfo: {
avatar: '',
nickname: ''
}
})
}
}
])
}
实现步骤:
1、在api.js 中,添加请求拦截器 (API.interceptors.request.user())
2、获取到当前请求的接口路径(url)
3、判断接口路径,是否以/user 开头,并且不是登录或注册接口(只给需要的接口添加请求头)
4、如果是,就添加请求头Authorization
5、添加响应拦截器 (API.interceptors.response.use())
6、判断返回值中的状态码
7、如果是400,标示token超时或异常,直接移除token
代码示例:
在src/utils/api.js中添加如下代码:
// 添加请求拦截器
API.interceptors.request.use(config => {
const { url } = config
// 判断请求url路径
if (
url.startsWith('/user') &&
!url.startsWith('/user/login') &&
!url.startsWith('/user/registered')
) {
// 添加请求头
config.headers.Authorization = getToken()
}
return config
})
// 添加响应拦截器
API.interceptors.response.use(response => {
const { status } = response.data
if (status === 400) {
// 此时,说明 token 失效,直接移除 token 即可
removeToken()
}
return response
})
实现原理:
1、限制某个页面只能在登陆的情况下访问,但是在React路由中并没有直接提供该组件,需要手动封装,来实现登陆访问控制(类似与Vue路由的导航守卫)
2、AuthRoute 组件实际上就是对原来Route组件做了一次包装,来实现一些额外的功能
3、render方法:render props模式,指定该路由要渲染的组件内容
4、Redirect组件:重定向组件,通过to属性,指定要跳转的路由信息
实现步骤:
1、在components目录中创建AuthRoute/index.js 文件
2、创建组件AuthRoute并导出
3、在AuthRoute组件中返回Route组件(在Route基础上做了一层包装,用于实现自定义功能)
4、给Route组件,添加render方法,指定改组件要渲染的内容(类似与component属性)
5、在render方法中,调用isAuth() 判断是否登陆
6、如果登陆了,就渲染当前组件(通过参数component获取到要渲染的组件,需要重命名)
7、如果没有登陆,就重定向到登陆页面,并且指定登陆成功后要跳转的页面路径
8、将AuthRoute组件接收到的props原样传递给Route组件(保证与Route组件使用方式相同)
9、使用AuthRoute组件配置路由规则,验证是否实现页面的登陆访问控制
代码示例:
在src/components/AuthRoute/index.js中添加如下代码:
const AuthRoute = ({ component: Component, ...rest }) => {
return (
{
const isLogin = isAuth()
if (isLogin) {
// 已登录
// 将 props 传递给组件,组件中才能获取到路由相关信息
return
} else {
// 未登录
return (
)
}
}}
/>
)
}
export default AuthRoute
实现步骤:
1、登陆成功后,判断是否需要跳转到用户想要访问的页面(判断props.location.state 是否有值)
2、如果不需要,则直接调用history.go(-1) 返回上一页
3、如果需要,就跳转到from.pathname 指定的页面(推荐使用replace方法模式,不是push)
代码示例:
在src/pages/Login/index.js中添加如下代码:
// 表单的提交事件
handleSubmit: async (values, { props }) => {
...
if (status === 200) {
// 登录成功
localStorage.setItem('hkzf_token', body.token)
if (!props.location.state) {
// 此时,表示是直接进入到了该页面,直接调用 go(-1) 即可
props.history.go(-1)
} else {
props.history.replace(props.location.state.from.pathname)
}
} else {
// 登录失败
Toast.info(description, 2, null, false)
}
}
打包步骤:
1、在根目录创建 .env.production 文件,配置生产环境的接口基础路径
2、在项目根目录中,打开终端
3、输入命令: yarn build,进行项目打包,生成build文件夹(打包好的项目内容)
4、将build目录中的文件内容,部署到都服务器中即可
5、打包成功后,在根目录中就会生成一个build文件夹
到此为止,我们的项目就已经全部开发完成了,由于篇幅有限,我们只展示了一部分的业务逻辑的编写,在真实的生产环境中,还要根据公司的需求去灵活运用这些知识。