// 登录拦截,没有路由守卫这个东西,需要拦截的话,可以自己去封装 Route
import React from "react";
import ReactDOM from 'react-dom'
import {
HashRouter as Router,
Route,
Link,
Redirect,
withRouter
} from "react-router-dom";
////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time
const AuthExample = () => (
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">公共页面</Link>
</li>
<li>
<Link to="/protected">需要登录验证的页面</Link>
</li>
{/* <li>
<Link to={{ pathname: '/login', state: { from: { pathname: '/abc' } } }}>登录页面</Link>
</li> */}
</ul>
<Route path="/public" component={Public} />
<Route path="/login" component={Login} />
{/* PrivateRoute 自定义 的路由组件实现路由拦截功能 通过将props,path="/protected" component={Protected}传过去*/}
<PrivateRoute path="/protected" component={Protected} />
</div>
</Router>
);
const fakeAuth = {
// fakeAuth登录的对象集合
isAuthenticated: false, // 登录状态
// 登录方法
authenticate(cb) {
this.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
// 退出登录方法
signout(cb) {
this.isAuthenticated = false;
setTimeout(cb, 100);
}
};
// withRouter 方法重新包装router
const AuthButton = withRouter(
({ history }) =>
// 登录状态 登录了就显示退出, 没有登录就显示没有登录
fakeAuth.isAuthenticated ? (
<p>
Welcome!{" "}
<button
onClick={() => {
// 函数式路由跳转
fakeAuth.signout(() => history.push("/"));
}}
>
退出登录
</button>
</p>
) : (
<p>You are not logged in.</p>
)
);
// 自己对 Route 组件做的一个封装。(高阶组件)
// props.path
// props.component
// rest = { path: '/protected' }
// 自己定义的一个Router组件,来实现路由拦截功能
// component: Component,将props中的component解构赋值出来并且实施重命名,应为下面是要作为组件使用
// ...rest 是接受剩下的元素
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
// 这是在路由中将剩余的props元素展开
{...rest} // 里面有路径 和路由页面的三props属性
render={
//这里的props是路由三prop
props =>
// 登录对象集合中的登录状态
fakeAuth.isAuthenticated ? (
// 为true 就显示该组件
<Component {...props} />
) : (
<Redirect
// 登录状态为false时重定向到登录页面
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
const Public = () => <h3>公共页面</h3>;
const Protected = () => <h3>需要登录的页面</h3>;
//登录页面
class Login extends React.Component {
state = {
// 登录状态
redirectToReferrer: false
};
login = () => {
// 点击登录时触发登录方法
fakeAuth.authenticate(() => {
// 将redirectToReferrer登录状态转变为true
this.setState({ redirectToReferrer: true });
});
};
render() {
// 解构赋值到 from 有传递过来想去的页面就去这个页面 没有的话就去 /
const { from } = this.props.location.state || { from: { pathname: "/" } };
const { redirectToReferrer } = this.state;
// 如果登录状态为true 就重定向到from页面
if (redirectToReferrer) {
return <Redirect to={from} />;
}
return (
<div>
<p>你还没有权限需要先登录 {from.pathname}</p>
<button onClick={this.login}>登录</button>
</div>
);
}
}
// export default AuthExample;
ReactDOM.render(<AuthExample />, document.getElementById('root'))
网友评论