Pārlūkot izejas kodu

React day9上:路由拦截&鉴权组件

daxia 1 gadu atpakaļ
vecāks
revīzija
3f262c5622

+ 20 - 0
20_React.js_VIP22/day-8下/code/react-project-demo/src/components/RequireAuth.jsx

@@ -0,0 +1,20 @@
+import { Navigate, useLocation } from 'react-router-dom';
+
+function RequireAuth({ children }) {
+  const token = localStorage.getItem('token');
+  const { pathname, search } = useLocation();
+
+  //! 如果token有值 那么默认认为登录过,就放行
+  if (token) {
+    return children;
+  }
+  //! 否则没有登录,就通过navigate组件实现页面跳转,导航到登录去并将其要去的地址通过查询参数记录起来
+  return (
+    <Navigate
+      to={{ pathname: '/login', search: `?r=${pathname + search}` }}
+      replace
+    />
+  );
+}
+
+export default RequireAuth;

+ 37 - 6
20_React.js_VIP22/day-8下/code/react-project-demo/src/pages/Login/index.jsx

@@ -1,14 +1,41 @@
-import { Button, Form, Input } from 'antd';
+import { Button, Form, Input, message } from 'antd';
 import { login } from '../../api/user';
 import './index.scss';
+import { UserOutlined, KeyOutlined } from '@ant-design/icons';
+import { useDispatch } from 'react-redux';
+import { setUser } from '../../store/slice/user';
+import { useNavigate, useSearchParams } from 'react-router-dom';
 
-const onFinish = async (values) => {
-  let { data } = await login(values);
+const onLogin = async (user, { dispatch, navigate }, to = '/') => {
+  let {
+    data: { code, msg, data },
+  } = await login(user);
 
-  console.log(data);
+  if (code == 0) {
+    message.success(msg);
+
+    //! 存token
+    localStorage.setItem('token', data.token);
+    //! redux存储用户信息
+    dispatch(setUser(data.user));
+    //! 跳转页面:如果有查询参数r 就 到r的地址,否则 去主页
+    navigate(to);
+    return;
+  }
+
+  message.error(msg);
 };
 
 function Login() {
+  const dispatch = useDispatch();
+  const navigate = useNavigate();
+  const [searchParams] = useSearchParams();
+  const to = searchParams.get('r') ? searchParams.get('r') : undefined;
+
+  function onFinish(values) {
+    onLogin(values, { dispatch, navigate }, to);
+  }
+
   return (
     <div className="login_container">
       <div className="login">
@@ -37,7 +64,7 @@ function Login() {
               },
             ]}
           >
-            <Input />
+            <Input prefix={<UserOutlined />} placeholder="账号..." allowClear />
           </Form.Item>
 
           <Form.Item
@@ -50,7 +77,11 @@ function Login() {
               },
             ]}
           >
-            <Input.Password />
+            <Input.Password
+              prefix={<KeyOutlined />}
+              placeholder="密码..."
+              allowClear
+            />
           </Form.Item>
 
           <Form.Item

+ 4 - 6
20_React.js_VIP22/day-8下/code/react-project-demo/src/pages/Login/index.scss

@@ -5,18 +5,16 @@
 
   justify-content: center;
   align-items: center;
+  background-image: url(./login.bg.gif);
 
 
   .login {
     width: 540px;
-    
     padding-top: 24px;
-
-    border: 1px solid #ccc;
     border-radius: 8px;
-
-    box-shadow: 0 0 2px 1px #ccc, inset 0 0 3px 2px #ccc;;
-
+    box-shadow: 0 0 2px 1px #fff;
+    background-color: rgba(255, 255, 255, .2);
+    backdrop-filter: blur(5px);
 
     h3 {
       text-align: center;

BIN
20_React.js_VIP22/day-8下/code/react-project-demo/src/pages/Login/login.bg.gif


+ 6 - 1
20_React.js_VIP22/day-8下/code/react-project-demo/src/router/index.js

@@ -2,6 +2,7 @@ import { createBrowserRouter } from 'react-router-dom';
 
 import { lazy } from 'react';
 import LayoutAdmin from '../Layout';
+import RequireAuth from '../components/RequireAuth';
 
 import Home from '../pages/Home';
 import withSuspense from '../utils/withSuspense';
@@ -16,7 +17,11 @@ const router = createBrowserRouter([
   },
   {
     path: '/',
-    element: <LayoutAdmin />,
+    element: (
+      <RequireAuth>
+        <LayoutAdmin />
+      </RequireAuth>
+    ),
     children: [
       {
         index: true,

+ 3 - 1
20_React.js_VIP22/day-8下/code/react-project-demo/src/store/index.js

@@ -1,9 +1,11 @@
 import { configureStore } from '@reduxjs/toolkit';
 import loadingReducer from './slice/loading';
+import userReducer from './slice/user';
 
 const store = configureStore({
   reducer: {
-    loading: loadingReducer,
+    loader: loadingReducer,
+    user: userReducer,
   },
 });
 

+ 17 - 0
20_React.js_VIP22/day-8下/code/react-project-demo/src/store/slice/user.js

@@ -0,0 +1,17 @@
+import { createSlice } from '@reduxjs/toolkit';
+
+export const userSlice = createSlice({
+  name: 'user',
+  initialState: {
+    userInfo: {},
+  },
+  reducers: {
+    setUser(state, { payload }) {
+      state.userInfo = payload;
+    },
+  },
+});
+
+export const { setUser } = userSlice.actions;
+
+export default userSlice.reducer;