尝试现场演示
Admiral 是一个用于在 React 中创建后台的前端框架。它提供了开箱即用的组件和工具,使管理界面的开发变得简单快捷。
用?由 dev.family 提供
要求:
安装 Admiral 有多种选项:
要使用 npx,请确保您有Node.js
npx create-admiral-app@latest
当您在控制台中输入此命令时,您将看到 2 个安装选项:
如果您选择“在 Express.js 上安装带有后端设置的模板”,您将在 Express.js 上安装带有后端的完全自定义模板。
详细的安装和启动说明
所有环境变量都会自动设置。如果您想手动配置它们,请转到项目文件夹并打开.env。从一开始你就会有 1 个 CRUD -用户。要找到他们,请通过 - admiral/src/crud/users/index.tsx
如果您选择“安装模板而不使用后端设置”,您将仅在 admiral 文件夹中通过 CRUD- Users获得 Admiral 的前端 shell。要找到它,请通过 - admiral/src/crud/users/index.tsx
。要使用您的后端,请阅读文档
Admiral 的地址为 http://localhost:3000。如果端口 3000 繁忙,则将选择任何其他空闲端口。
在控制台中你会看到类似这样的内容
Port 3000 is in use, trying another one...
vite v2.9.15 dev server running at:
> Local: http://localhost:3001/
> Network: http://192.168.100.82:3001/
ready in 459ms.
每个示例中都有详细的安装和启动说明。
打开浏览器并访问 http://localhost:3000。
是的,没错。您可以克隆此存储库并输入以下命令:
yarn
yarn dev
然后访问http://localhost:3000。现在您可以使用带有模拟数据的海军上将。
App.tsx 文件是应用程序的入口点。这是库初始化的地方以及组件渲染的地方Admin
。
import React from 'react'
import { Admin , createRoutesFrom , OAuthProvidersEnum } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
const apiUrl = '/api'
// import all pages from pages folder and create routes
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >
)
}
export default App
系统中授权的主要契约是接口AuthProvider
。
export interface AuthProvider {
login : ( params : any ) => Promise < any >
logout : ( params : any ) => Promise < void | false | string >
checkAuth : ( params : any ) => Promise < void >
getIdentity : ( ) => Promise < UserIdentity >
oauthLogin ?: ( provider : OAuthProvidersEnum ) => Promise < { redirect : string } >
oauthCallback ?: ( provider : OAuthProvidersEnum , data : string ) => Promise < any >
[ key : string ] : any
}
实现示例 接口本身可以根据您的喜好进行定制,但尊重它提供的契约很重要。详细合同说明
我们看一下基本的实现方法:
方法 | 姓名 | 描述 | 参数 | 返回值 |
---|---|---|---|---|
登录 | 用户认证 | 向/api/login 发出 POST 请求,并将token 字段存储在 localStorage 中,以供后续请求使用 | params - 包含username 和password 的对象 | 具有token 字段的对象和具有email 和name 字段的user 对象 |
注销 | 用户注销 | 向/api/logout 发出 POST 请求并从 localStorage 中删除token 字段 | void | |
检查验证 | 用户授权检查 | 向/api/checkAuth 发出 GET 请求并检查令牌有效性,需要状态代码 - 200。每次使用 API 时使用 | 不记名token | 状态码200 |
获取身份 | 接收用户数据 | 向/api/getIdentity 发出 GET 请求并返回包含用户数据的对象 | 不记名token | 具有email 和name 字段的对象user |
登录 | 通过 OAuth 授权 | 向/api/auth/social-login/${provider} 发出 GET 请求并返回带有redirect 字段的对象,该对象用于重定向 | provider - OAuth 提供商 | 具有字段redirect 的对象 |
oauth回调 | 通过OAuth回调授权 | 向/api/auth/social-login/${provider}/callback 发出 POST 请求,并将token 字段存储在 localStorage 中,以在进一步的请求中使用 | provider - OAuth 提供商, data - 从存在token 字段的 OAuth 提供商接收的数据 | 带有字段token 对象 |
处理数据的主要合约代表接口DataProvider
。
export interface DataProvider {
getList : (
resource : string ,
params : Partial < GetListParams > ,
) => Promise < GetListResult < RecordType > >
reorderList : ( resource : string , params : ReorderParams ) => Promise < void >
getOne : ( resource : string , params : GetOneParams ) => Promise < GetOneResult < RecordType > >
getCreateFormData : ( resource : string ) => Promise < GetFormDataResult < RecordType > >
getFiltersFormData : (
resource : string ,
urlState ?: Record < string , any > ,
) => Promise < GetFiltersFormDataResult >
create : ( resource : string , params : CreateParams ) => Promise < CreateResult < RecordType > >
getUpdateFormData : (
resource : string ,
params : GetOneParams ,
) => Promise < GetFormDataResult < RecordType > >
update : ( resource : string , params : UpdateParams ) => Promise < UpdateResult < RecordType > >
deleteOne : ( resource : string , params : DeleteParams ) => Promise < DeleteResult < RecordType > >
[ key : string ] : any
}
实施示例 详细的合同描述
我们看一下基本的实现方法:
方法 | 姓名 | 描述 | 参数 |
---|---|---|---|
获取列表 | 获取实体列表 | 向/api/${resource} 发出 GET 请求并返回一个对象,其中包含要在List 组件中使用的数据 | resource - 资源名称, params - 带有查询参数的对象 |
重新排序列表 | 更改实体的顺序 | 向/api/${resource}/reorder 发出 POST 请求并返回一个对象,其中包含要在List 组件中使用的数据 | resource - 资源名称, params - 带有查询参数的对象 |
得到一个 | 获取实体 | 向/api/${resource}/${id} 发出 GET 请求并返回一个对象,其中包含要在Show 组件中使用的数据 | resource - 资源名称, id - 实体标识符 |
获取创建表单数据 | 获取实体创建表单的数据(Select、AjaxSelect) | 向/api/${resource}/create 发出 GET 请求并返回一个对象,其中包含要在Create 组件中使用的数据 | resource -资源名称 |
获取过滤器表单数据 | 接收过滤器数据 | 向/api/${resource}/filters 发出 GET 请求并返回一个对象,其中包含要在Filters 组件中使用的数据 | resource - 资源名称, urlState - 带有要在组件Filters 中使用的 url 参数的对象 |
创造 | 创建实体 | 向/api/${resource} 发出 POST 请求并返回一个对象,其中包含要在组件Create 中使用的数据 | resource - 资源名称, params - 实体数据对象 |
获取更新表单数据 | 获取实体编辑表单的数据(Select、AjaxSelect) | 向/api/${resource}/${id}/update 发出 GET 请求并返回一个对象,其中包含要在组件Edit 中使用的数据 | resource - 资源名称, id - 实体标识符 |
更新 | 更新实体 | 向/api/${resource}/${id} 发出 POST 请求并返回一个对象,其中包含要在组件Edit 中使用的数据 | resource - 资源名称, id - 实体标识符, params - 实体数据对象 |
删除 | 删除实体 | 向/api/${resource}/${id} 发出 DELETE 请求并返回一个包含要在Delete 组件中使用的数据的对象 | resource - 资源名称, id - 实体标识符 |
询问:
http://localhost/admin/users?page=1&perPage=10&filter%5Bid%5D=1
结果:
{
"items" : [
{
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role" : " Administrator " ,
"created_at" : " 2023-05-05 14:17:51 "
}
],
"meta" : {
"current_page" : 1 ,
"from" : 1 ,
"last_page" : 1 ,
"per_page" : 10 ,
"to" : 1 ,
"total" : 1
}
}
询问:
http://localhost/admin/users/1/update?id=1
结果:
{
"data" : {
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role_id" : 1
},
"values" : {
"role_id" : [
{
"label" : " Administrator " ,
"value" : 1
}
]
}
}
❗注意:我们利用 HTTP 状态代码 422 Unprocessable Entity 来处理验证错误。
{
"errors" : {
"name" : [ " Field 'name' is invalid. " ],
"email" : [ " Field 'email' is invalid. " ]
},
"message" : " Validation failed "
}
分页与getList
方法一起使用。您可以将page
和perPage
参数传递给getList
方法,它将返回带有items
和meta
字段的PaginationResult
对象。
过滤器与getList
方法一起使用。您可以将filter[$field]
参数传递给getList
方法,它将返回带有items
和meta
字段的PaginationResult
对象。
使用getList
方法进行排序。您可以将sort[$field]
参数传递给getList
方法,它将返回带有items
和meta
字段的PaginationResult
对象。
Admiral 有一个基于文件系统的路由器。
页面是从页面目录中的 .js、.jsx、.ts 或 .tsx 文件导出的 React 组件。当文件添加到页面目录时,它会自动作为路由使用。 React-router-dom 在幕后使用。
路由器会自动将名为index的文件路由到目录的根目录。
pages/index.ts → /
pages/users/index.ts → /users
路由器支持嵌套文件。如果您创建嵌套文件夹结构,文件仍将以相同的方式自动路由。
pages/users/create.ts → /users/create
要匹配动态段,可以使用括号语法。这允许您匹配命名参数。
pages/users/[id].ts → /users/:id (/users/42)
该组件是您的管理面板中最重要的组件。有了它,您可以设置应用程序的基本设置和配置,例如:导航、徽标、向服务器请求的 api、api 授权、本地化、主题等。
使用示例:
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >
该组件接受以下属性:
菜单
在这里您可以自定义您的导航。您应该使用我们包中的特殊组件:Menu、MenuItemLink、SubMenu。您可以在这里找到一个示例。
标识
您可以更改旁边导航栏中显示的徽标。该属性接受 svg、JSX 组件或 svg 格式文件的链接。
登录标志
您可以更改授权表中显示的徽标。该属性接受 svg、JSX 组件或 svg 格式文件的链接。
旁白内容
使用此工具,您可以将必要的内容添加到链接下方的旁侧导航栏。你必须通过ReactNode。
数据提供者
处理数据的主要合同。您可以在我们的文档中获取更多信息。
授权提供者
系统中授权的主合约。您可以在我们的文档中获取更多信息。
主题预设
您可以为您的应用程序自定义颜色主题。您可以在我们的文档中获取更多信息。
语言环境
管理面板的本地化方案,您可以使用 useLocaleProvider 挂钩获取。您可以在此处找到该方案的示例。
oauthProviders
使用此道具进行 OAuth 授权。使用来自 admiral 的 OAuthProvidersEnum 枚举在数组中传递所需提供者的名称。
基本应用程序 URL
添加道具以更改应用程序的基本路径。
菜单是具有以下结构的对象数组:
import { Menu , SubMenu , MenuItemLink } from '../../admiral'
const CustomMenu = ( ) => {
return (
< Menu >
< MenuItemLink icon = "FiCircle" name = "First Menu Item" to = "/first" />
< SubMenu icon = "FiCircle" name = "Second Menu Item" >
< MenuItemLink icon = "FiCircle" name = "Sub Menu Item" to = "/second" />
</ SubMenu >
</ Menu >
)
}
export default CustomMenu
我们的应用程序使用 React hooks。您可以在 React 组件内的应用程序中的任何位置使用它们。这些是您可以使用的钩子:
该钩子允许您接收和管理导航栏的状态
import { useNav } from '@devfamily/admiral'
const { collapsed , toggleCollapsed , visible , toggle , open , close } = useNav ( )
该挂钩允许您获取表单值并管理表单的状态。该钩子可以在 createCRUD 函数配置中的“form”中使用的组件中使用。
import { useForm } from '@devfamily/admiral'
const {
values ,
options ,
errors ,
setErrors ,
setValues ,
setOptions ,
isSubmitting ,
isFetching ,
locale ,
} = useForm ( )
该挂钩允许您接收和管理主题的状态。
import { useTheme } from '@devfamily/admiral'
const { themeName , setTheme } = useTheme ( )
一个钩子,允许您获取通过调用 AuthProvider.getIdentity() 获得的状态
import { useGetIdentty } from '@devfamily/admiral'
const { identity , loading , loaded , error } = useGetIdentty ( )
Admiral 中使用的图标来自 React Icons。
ThemeProvider 在底层使用 @consta/uikit 主题组件。
您可以使用themePresets
属性将预设传递给Admin
组件:
import React from 'react'
import { Admin , createRoutesFrom } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
import themeLight from './theme/presets/themeLight'
import themeDark from './theme/presets/themeDark'
const apiUrl = '/api'
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
themePresets = { { light : themeLight , dark : themeDark } }
>
< Routes />
</ Admin >
)
}
创建预设目录。在每个修饰符的 make 文件夹中 - 与主题组件中的相同。
创建 CSS 文件。在带有修饰符的文件夹中放置负责这些修饰符的 CSS 文件。
你会得到类似的东西:
presets/
_color/
_Theme_color_themeDark.css
_Theme_color_themeLight.css
_control/
_Theme_control_themeLight.css
_font/
_Theme_font_themeLight.css
_size/
_Theme_size_themeLight.css
_space/
_Theme_space_themeLight.css
_shadow/
_Theme_shadow_themeLight.css
themeLight.ts
themeDark.ts
配置 CSS 文件中的变量。
创建预设文件(themeLight、themeDark)。
导入您要使用的 CSS 文件。
创建预设对象。指定在预设中使用哪些修饰符的哪些值(即 CSS 文件)。你会得到类似的东西:
// in presets/themeLight.ts
import './_color/_Theme_color_themeLight.css'
import './_color/_Theme_color_themeDark.css'
import './_control/_Theme_control_themeLight.css'
import './_font/_Theme_font_themeLight.css'
import './_size/_Theme_size_themeLight.css'
import './_space/_Theme_space_themeLight.css'
import './_shadow/_Theme_shadow_themeLight.css'
export default {
color : {
primary : 'themeLight' ,
accent : 'themeDark' ,
invert : 'themeDark' ,
} ,
control : 'themeLight' ,
font : 'themeLight' ,
size : 'themeLight' ,
space : 'themeLight' ,
shadow : 'themeLight' ,
}
将您的预设传递给Admin
组件,如上例所示。
❗注意:postcss 插件用于 admiral 预设示例中的颜色转换。如果你想重现,请设置 postcss 和 postcss-color-mod-function 插件。
如果您想参与 Admiral 的开发,请对存储库进行分叉,进行所需的更改并发送拉取请求。我们很乐意考虑您的建议!
该库是根据 MIT 许可证分发的。
如果您有任何疑问,请通过以下方式联系我们:[email protected] 我们很高兴收到您的反馈!