React-Router
Это очень важная часть экосистемы React. Теперь маршрутизация одностраничных приложений React в основном управляется самим внешним интерфейсом, в отличие от внутренней маршрутизации в прошлом. Обычно используемая библиотека для маршрутизации управления React:React-Router
. Я хочу написать эту статьюReact-Router
Использование , но введение API слишком мягкое,И официальная документация написана очень хорошо, я буду использовать общий сценарий разработки, чтобы увидетьReact-Router
Как это используется. Наша общая система будет иметь ограничения на права доступа пользователей, и некоторые страницы могут требовать, чтобы пользователи имели определенные права доступа. В этой статье используетсяReact-Router
Для реализации модели внешней аутентификации.
Весь код в этой статье был загружен на GitHub, вы можете снять его и поиграть:GitHub.com/Денис — см....
Пример приложения
Функция, которая будет реализована в этой статье, представляет собой сценарий, с которым часто сталкиваются все, то есть управление разными ролями пользователей для доступа к разным страницам.Всего здесь четыре страницы:
/index
: домашняя страница сайта/login
: страница авторизации/backend
: Фоновая страница/admin
: Страница управления
Есть также три другие роли:
未登录用户
: Доступ возможен только к домашней странице веб-сайта./index
и страница входа/login
普通用户
: Вы можете посетить домашнюю страницу веб-сайта/index
, страница авторизации/login
и бэкэнд-страница/backend
管理员
: Может получить доступ к странице администратора/admin
и все остальные страницы
Представляем React-маршрутизатор
Чтобы реализовать маршрутную аутентификацию, нам нужно идти шаг за шагом.Сначала мы используем React-Router для создания простого проекта с этими страницами. мы напрямую используемcreate-react-app
Создал новый проект, затем построилpages
Папка, содержащая упомянутые ранее страницы:
Давайте сначала напишем простую страницу, давайте сначала напишем заголовок, например:
import React from 'react';
function Admin() {
return (
<h1>管理员页面</h1>
);
}
Несколько других страниц похожи.
Тогда мы можемApp.js
импорт внутриReact-Router
Сделайте скачок маршрутизации, обратите внимание на то, что мы используем в браузереreact-router-dom
, новая версияReact-Router
Уровень основной логики и уровень представления разделены. Основная логика обрабатывает сопоставление маршрутов и т. д., а уровень представления обрабатывает фактические переходы и отслеживание изменений маршрута. Причина такого разделения заключается в том, что React-Router должен поддерживать не только браузеры. , но также нужно поддерживать React Native, мониторинг и прыжки этих двух платформ разные, так что теперьReact-RouterНиже представлено несколько пакетов:
react-router
: основная логическая обработка, предоставляющая некоторые общие базовые классы.
react-router-dom
: Специальная реализация мониторинга маршрутизации и переходов, связанных с браузером.
react-router-native
: Конкретная реализация мониторинга маршрутизации и перехода, связанного с RN.
В реальном использовании нам, как правило, не нужно ссылаться наreact-router
, но напрямую использоватьreact-router-dom
Просто отлично, потому что он будет цитировать сам себяreact-router
. Ниже мы вводим в проектreact-router-dom
.
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
} from "react-router-dom";
import Home from './pages/Home';
import Login from './pages/Login';
import Backend from './pages/Backend';
import Admin from './pages/Admin';
function App() {
return (
<Router>
<Switch>
<Route path="/login" component={Login}/>
<Route path="/backend" component={Backend}/>
<Route path="/admin" component={Admin}/>
<Route path="/" component={Home}/>
</Switch>
</Router>
);
}
export default App;
тогда ты можешьHome
страницаLink
Добавьте ссылки для перехода на другие страницы, чтобы вы могли перейти:
import React from 'react';
import { Link } from 'react-router-dom';
function Home() {
return (
<>
<h1>首页</h1>
<ul>
<li><Link to="/login">登录</Link></li>
<li><Link to="/backend">后台</Link></li>
<li><Link to="/admin">管理员</Link></li>
</ul>
</>
);
}
export default Home;
Пока что наше приложение работает так:
Модульное деление
Хотя наш прыжок реализован, каждый может получить доступ к любой странице.Наше предыдущее требование - ограничить доступ к страницам в соответствии с ролью входа.Прежде чем писать код, давайте подумаем, как это сделать. Конечно, самый интуитивно понятный и простой способ — определить роль текущего пользователя на каждой странице и сообщить об ошибке или вернуться на домашнюю страницу, если она не совпадает. У нас сейчас всего несколько страниц, и это вроде бы нормально, но если наше приложение станет больше и страниц будет больше, то проверять каждую страницу по одному разу будет очень многократно, поэтому стоит подумать об этой проблеме под другим углом.
Присмотревшись повнимательнее, мы на самом деле имеем три роли, соответствующие трем разным разрешениям. Эти три разрешения также связаны иерархически. Разрешения высокого уровня включают в себя разрешения более низкого уровня, поэтому наши страницы также можно разделить на эти разрешения.
公共页面
: может быть доступен всем, даже без входа в систему, включая домашнюю страницу и страницу входа на веб-сайт.普通页面
: страницы, к которым могут получить доступ обычные пользователи, вошедшие в систему.管理员页面
: страница, доступ к которой имеют только администраторы
Чтобы управлять этими тремя видами страниц, мы можем извлечь их в три файла и поместить в отдельную папку.routes
Внутри три файла называютсяpublicRoutes.js
,privateRoutes.js
,adminRoutes.js
:
Для каждого файла маршрута мы можем организовать такие маршруты в массив, затемexport
Выйдите, чтобы позвонить снаружи, напримерpublicRoutes.js
:
import Login from '../pages';
import Home from '../pages/Home';
const publicRoutes = [
{
path: '/login',
component: Login,
exact: true,
},
{
path: '/',
component: Home,
exact: true,
},
];
export default publicRoutes;
Затем место, которое мы используем снаружи, напрямую изменяется на:
import publicRoutes from './routes/publicRoutes';
function App() {
return (
<Router>
<Switch>
{publicRoutes.map(
({path, component, ...routes}) =>
<Route key={path} path={path} component={component} {...routes}/>
)}
<Route path="/backend" component={Backend}/>
<Route path="/admin" component={Admin}/>
</Switch>
</Router>
);
}
так что нашApp.js
Не будет длинного списка маршрутизации, а будет просто циклический обход массива. Но для страниц, которые требуют входа в систему для доступа и страниц администрирования, мы не можем отображать их напрямую.Route
компонента, нам лучше инкапсулировать высокоуровневый компонент и поместить работу аутентификации в этот компонент, чтобы нашей обычной странице не нужно было заботиться о том, как аутентифицироваться при ее реализации.
Упаковка передовых компонентов
Идея инкапсуляции этого компонента аутентификации также очень проста.publicRoutes
Непосредственно используется для рендеринга циклаRoute
компонента, нашему компоненту аутентификации нужно только добавить логику на этой основе: при рендеринге реальногоRoute
Перед компонентом проверьте, есть ли у текущего пользователя соответствующее разрешение, и если да, отрендерите его напрямуюRoute
Если компонента нет, он вернется на определенную страницу, которая может быть страницей входа или фоновой домашней страницей, в зависимости от потребностей вашего собственного проекта. Итак, наш файл конфигурации маршрутизацииprivateRoutes.js
,adminRoutes.js
Маршрутизация внутри будет лучше, чемpublicRoutes.js
еще два параметра:
// privateRoutes.js
import Backend from '../pages/Backend';
const privateRoutes = [
{
path: '/backend',
component: Backend,
exact: true,
role: 'user', // 当前路由需要的角色权限
backUrl: '/login' // 不满足权限跳转的路由
},
];
export default privateRoutes;
adminRoutes.js
похоже на запись:
// adminRoutes.js
import Admin from '../pages/Admin';
const adminRoutes = [
{
path: '/admin',
component: Admin,
exact: true,
role: 'admin', // 需要的权限是admin
backUrl: '/backend' // 不满足权限跳回后台页面
},
];
export default adminRoutes;
Затем мы можем написать наш высокоуровневый компонент, который мы назовем какAuthRoute
Обратите внимание, что backend API вернет роль текущего пользователя, когда пользователь войдет в систему. Пользователь может иметь несколько ролей. Например, роль обычного пользователя['user']
, роль администратора['user', 'admin']
, конкретная логика проверки разрешений зависит от дизайна разрешений вашего собственного проекта, вот только пример:
// AuthRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
function AuthRoute(props) {
const {
user: {
role: userRole
},
role: routeRole,
backUrl,
...otherProps
} = props;
// 如果用户有权限,就渲染对应的路由
if (userRole && userRole.indexOf(routeRole) > -1) {
return <Route {...otherProps} />
} else {
// 如果没有权限,返回配置的默认路由
return <Redirect to={backUrl} />
}
}
export default AuthRoute;
тогда используйте нашAuthRoute
оказаниеadminRoutes
а такжеprivateRoutes
:
// ... 省略其他代码 ...
{privateRoutes.map(
(route) => <AuthRoute key={route.path} {...route}/>
)}
{adminRoutes.map(
(route) => <AuthRoute key={route.path} {...route}/>
)}
Войдите, чтобы установить разрешения
в нашемAuthRoute
используется вuser: { role }
эту переменную, но мы еще не установили ее. В реальных проектах при входе back-end API будет возвращать роль текущего пользователя, а затем front-end будет сохранять эту информацию о разрешениях в некоторых инструментах управления состоянием, таких какRedux
. мы здесь прямоLogin
На странице написано две кнопки для имитации этого разрешения, а в конфигурации пользователя используется корневой компонент.state
приходите управлять,Login
Две кнопки на странице изменят соответствующиеstate
:
import React from 'react';
import { Link } from 'react-router-dom';
function Login(props) {
const {loginAsUser, loginAsAdmin, history} = props;
const userLoginHandler = () => {
loginAsUser(); // 调用父级方法设置用户权限
history.replace('/backend'); // 登录后跳转后台页面
}
const adminLoginHandler = () => {
loginAsAdmin(); // 调用父级方法设置管理员权限
history.replace('/admin'); // 登录后跳转管理员页面
}
return (
<>
<h1>登录页</h1>
<button onClick={userLoginHandler}>普通用户登录</button>
<br/><br/>
<button onClick={adminLoginHandler}>管理员登录</button>
<br/><br/>
<Link to="/">回首页</Link>
</>
);
}
export default Login;
На этом наша простая аутентификация маршрутизации завершена.Конкретный эффект выполнения выглядит следующим образом:
Весь код в этой статье был загружен на GitHub, вы можете снять его и поиграть:GitHub.com/Денис — см....
Суммировать
-
React-Router
Его можно использовать для управления скачком маршрутизации внешнего интерфейса, даReact
Очень важная библиотека в экологии. -
React-Router
Для поддержки как браузера, так иReact-Native
, он разделился на три пакетаreact-router
основной пакет,react-router-dom
пакет браузера,react-router-native
служба поддержкиReact-Native
. Нет необходимости импортировать при использованииreact-router
, просто импортируйте необходимый пакет платформы. - Для маршрутов, требующих разных прав, мы можем их вынести и классифицировать в отдельный файл, а если маршрутов немного, то также можно экспортировать несколько массивов в один файл.
- Для маршрутов, требующих аутентификации, мы можем использовать расширенный компонент, чтобы инкапсулировать в нем логику проверки разрешений, а остальные страницы нужно только настроить, и нам вообще не нужно заботиться об аутентификации.
Содержание этой статьи относительно простое, какReact-Router
Использование неплохое, но мы можем не просто использовать его, но и знать его принцип. Следующая статья давайте посмотримReact-Router
Какие загадки в исходном коде ?
использованная литература
Официальная документация:react-router.com/Web/guides/…
Адрес источника GitHub:GitHub.com/реагировать поезд я…
В конце статьи спасибо, что потратили свое драгоценное время на чтение этой статьи. Если эта статья немного поможет вам или вдохновит, пожалуйста, не скупитесь на лайки и звезды GitHub. Ваша поддержка является движущей силой для автор продолжать творить.
Добро пожаловать, чтобы обратить внимание на мой общедоступный номербольшой фронт атакиПолучите высококачественные оригиналы впервые~
Цикл статей "Передовые передовые знания":nuggets.capable/post/684490…
Адрес GitHub с исходным кодом из серии статей «Advanced Front-end Knowledge»:GitHub.com/Денис — см....