refine Ant Design<AuthPage>组件实战:登录、注册与密码重置页的类型、Props 与源码解析
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
本文围绕 refine 中 Ant Design 集成的<AuthPage>组件展开,完整讲解其四种页面类型(login / register / forgotPassword / updatePassword)的路由接入方式、全部 Props(providers、rememberMe、各导航链接、wrapperProps、contentProps、formProps、renderContent)的用法与默认值,并结合当前仓库源码说明表单提交到authProvider的完整调用链,帮助你在基于 refine 构建后台系统时快速搭建可定制的全套认证页面。
组件概述
<AuthPage>是 refine 为Ant Design提供的认证页面组件,一个组件即可承载登录、注册、忘记密码和更新密码四种页面,通过type属性区分:
| type 值 | 用途 | 表单字段(源码确认) |
|---|---|---|
login | 登录页,默认类型 | email、password、remember(初始值false) |
register | 注册页 | email、password |
forgotPassword | 忘记密码页 | |
updatePassword | 更新密码页 | password、confirmPassword(含两次输入一致性校验) |
从源码结构看,AuthPage 入口 本身只是一个分发器:
export const AuthPage: React.FC<AuthProps> = (props) => { const { type } = props; const renderView = () => { switch (type) { case "register": return <RegisterPage {...props} />; case "forgotPassword": return <ForgotPasswordPage {...props} />; case "updatePassword": return <UpdatePasswordPage {...props} />; default: return <LoginPage {...props} />; } }; return <>{renderView()}</>; };四种页面分别实现于 login、register、forgotPassword、updatePassword 目录下,公共视觉样式(卡片最大宽度 400px、内边距 32px、标题 24px 等)收敛在 styles.ts 中。
使用前提:必须先为<Refine>配置authProvider,由它负责实际的登录、注册、改密逻辑。此外,<AuthPage>支持Swizzle——可以通过refine CLI把该组件复制到你的项目中,再在源码层面自由修改,而不必只依赖 Props。
基本用法
将<AuthPage>作为LoginPage传给<Refine>,并可在路由表中为注册、忘记密码页面各挂一条路由:
import { Refine } from "@pankod/refine-core"; import { AuthPage, Layout } from "@pankod/refine-antd"; import routerProvider from "@pankod/refine-react-router-v6"; import { authProvider } from "./authProvider"; import { DashboardPage } from "./pages/dashboard"; const App = () => { return ( <Refine routerProvider={{ ...routerProvider, routes: [ { path: "/register", element: <AuthPage type="register" />, }, { path: "/forgot-password", element: <AuthPage type="forgotPassword" />, }, ], }} authProvider={authProvider} LoginPage={AuthPage} DashboardPage={DashboardPage} Layout={Layout} resources={[{ name: "posts" }]} /> ); };说明两点:
LoginPage={AuthPage}未指定type,因此默认渲染login类型,路由通常为/login;register、forgotPassword、updatePassword三种类型需要通过routes自行声明路径(文档示例分别使用/register、/forgot-password、/update-password)。
四种类型详解
Login(默认)
登录页提交表单后,会调用authProvider的login方法并传入表单值:
import { AuthProvider } from "@pankod/refine-core"; const authProvider: AuthProvider = { // -- login: async ({ email, password, remember, providerName }) => { // You can handle the login process according to your needs. // If the process is successful. return Promise.resolve(); return Promise.reject(); }, // -- };从源码可以看到,LoginPage的 email 字段同时带有“必填”和type: "email"两条校验规则,password 字段必填;表单onFinish中执行login({ ...values, ...mutationVariables })。其中mutationVariables是<AuthPage>支持的透传参数,会把额外字段合并进authProvider.login的入参,适合传租户、渠道等上下文。登录过程中的加载态由useLogin返回的isPending驱动提交按钮的loading属性。
Register
注册页通过type="register"渲染,提交后调用authProvider.register:
const authProvider: AuthProvider = { // -- register: async ({ email, password, providerName }) => { // You can handle the register process according to your needs. return Promise.resolve(); return Promise.reject(); }, // -- };路由接入方式与基本用法一致:
const App = () => { return ( <Refine authProvider={authProvider} routerProvider={{ ...routerProvider, routes: [ { path: "/register", element: <AuthPage type="register" />, }, ], }} LoginPage={AuthPage} DashboardPage={DashboardPage} Layout={Layout} resources={[{ name: "posts" }]} /> ); };ForgotPassword
forgotPassword类型用于引导用户重置密码,提交后调用authProvider.forgotPassword,入参只有email:
const authProvider: AuthProvider = { // -- forgotPassword: async ({ email }) => { // You can handle the reset password process according to your needs. return Promise.resolve(); return Promise.reject(); }, // -- };UpdatePassword
updatePassword类型用于用户已登录场景下修改密码。从源码看,该表单包含password与confirmPassword两个字段,后者通过dependencies: ["password"]+ 自定义 validator 实现“两次密码不一致则拒绝提交”的前端校验,提交后调用authProvider.updatePassword:
const authProvider: AuthProvider = { // -- updatePassword: async ({ password, confirmPassword }) => { // You can handle the update password process according to your needs. return Promise.resolve(); return Promise.reject(); }, // -- };Props 详解
providers
仅对
login和register两种类型可用。
providers定义第三方登录(OAuth)按钮列表,接收OAuthProvider[]数组。点击任一按钮不会走表单,而是直接以providerName为参数调用对应的login/register:
const { GoogleOutlined, GithubOutlined } = Icons; const App = () => { return ( <Refine authProvider={authProvider} routerProvider={routerProvider} LoginPage={() => ( <AuthPage providers={[ { name: "google", icon: <GoogleOutlined />, label: "Sign in with Google", }, { name: "github", icon: <GithubOutlined />, label: "Sign in with GitHub", }, ]} /> )} DashboardPage={DashboardPage} Layout={Layout} resources={[{ name: "posts" }]} /> ); };数组元素结构由 core 包的 OAuthProvider 类型 定义:
interface OAuthProvider { name: string; icon?: React.ReactNode; label?: string; }源码中renderProviders()会为每个 provider 渲染一个block样式的 antdButton,点击时执行login({ ...mutationVariables, providerName: provider.name })(注册页同理调用register)。只要providers非空且未隐藏表单,组件还会自动在按钮与表单之间插入一条 "or" 分隔线。
rememberMe
仅对
login类型可用。
rememberMe用于渲染自定义的“记住我”组件;传false可完全移除该组件。默认值是一个带Remember me文案的 antdCheckbox。
自定义时有一个硬性约束:必须用 antd 的Form.Item包裹并传入name,这样它的值才会进入表单,才能在formProps.onFinish的formValues中读到。从源码看,默认实现的remember字段初始值为false:
LoginPage={() => ( <AuthPage rememberMe={ <div style={{ border: "1px dashed cornflowerblue", padding: 3 }}> <Form.Item name="remember" valuePropName="checked" noStyle> <Checkbox>Custom remember me</Checkbox> </Form.Item> </div> } /> )}loginLink
仅对
register和forgotPassword类型可用。
定义“去登录”的链接节点,也可以传任意 ReactNode 完全替换默认文案;默认值是渲染到/login的链接。
const Auth = (props) => { const { Link } = useRouterContext(); return ( <AuthPage {...props} loginLink={ <div style={{ border: "1px dashed cornflowerblue", padding: 3 }}> <Link to="/login">Login</Link> </div> } /> ); };registerLink
仅对
login类型可用。
定义登录页底部“去注册”的链接,默认渲染指向/register的链接(文案 "Don't have an account? Sign up")。同样可以传任意节点:
const Auth = (props) => { const { Link } = useRouterContext(); return ( <AuthPage {...props} registerLink={ <div style={{ border: "1px dashed cornflowerblue", marginTop: 5, padding: 5 }}> <Link to="/register">Register</Link> </div> } /> ); };forgotPasswordLink
仅对
login类型可用。
定义登录页“忘记密码”链接,默认渲染指向/forgot-password的链接:
const Auth = (props) => { const { Link } = useRouterContext(); return ( <AuthPage {...props} forgotPasswordLink={ <div style={{ border: "1px dashed cornflowerblue", marginTop: 5, padding: 5 }}> <Link to="/forgot-password">Forgot Password</Link> </div> } /> ); };wrapperProps
透传给最外层包裹组件(antdLayout)的 props,例如修改整页背景色:
LoginPage={() => ( <AuthPage wrapperProps={{ style: { background: "#331049", }, }} /> )}contentProps
透传给内容卡片组件(antdCard)的 props,可修改标题、头部与内容区样式:
LoginPage={() => ( <AuthPage contentProps={{ title: "Login", headStyle: { background: "cornflowerblue", color: "white", }, bodyStyle: { background: "#673ab742", }, }} /> )}formProps
透传给 antdForm的 props。典型用法包括修改initialValues与替换onFinish回调:
LoginPage={() => ( <AuthPage formProps={{ initialValues: { email: "demo@refine.dev", password: "demo", }, onFinish: (formValues) => alert(JSON.stringify(formValues, null, 2)), }} /> )}注意:默认onFinish会触发authProvider对应方法,重写onFinish意味着接管整个提交逻辑,需要自行处理认证调用。
renderContent
renderContent接收默认的content(卡片)与title(页头标题),返回完全自定义的内容,可在原有内容之外插入任意元素:
LoginPage={() => ( <AuthPage contentProps={{ style: { width: "400px", }, }} renderContent={(content: React.ReactNode) => { return ( <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", }} > <h1 style={{ color: "white" }}>Extra Header</h1> {content} <h1 style={{ color: "white" }}>Extra Footer</h1> </div> ); }} /> )}hideForm、title与mutationVariables(补充)
在 core 包的 AuthPageProps 类型定义 中还能看到三个 Props 文档:
hideForm?: boolean—— 隐藏表单主体,只保留 provider 按钮与链接,适合纯 OAuth 登录页;title?: React.ReactNode—— 替换卡片上方的页面标题,设为false则完全不渲染;mutationVariables?: Record<string, any>—— 额外变量,会与表单值一起合并传给authProvider的对应方法。
API Reference
Properties
| Property | Type | Default |
|---|---|---|
type | login|register|forgotPassword|updatePassword | login |
providers | OAuthProvider[] | - |
registerLink | React.ReactNode | 指向/register的链接 |
forgotPasswordLink | React.ReactNode | 指向/forgot-password的链接 |
loginLink | React.ReactNode | 指向/login的链接 |
rememberMe | React.ReactNode | <Checkbox>Remember me</Checkbox> |
hideForm | boolean | - |
wrapperProps | LayoutProps(antd) | - |
contentProps | CardProps(antd) | - |
formProps | FormProps(antd) | - |
renderContent | (content: ReactNode, title: ReactNode) => ReactNode | - |
title | React.ReactNode | - |
Interface
interface OAuthProvider { name: string; icon?: React.ReactNode; label?: string; }表单提交到 authProvider 的源码级调用链
四种页面共用同一套机制,以登录为例:
LoginPage内部通过 core 的useLogin获取 mutation:const { mutate: login, isPending } = useLogin<LoginFormTypes>();- antd
Form的onFinish={(values) => login({ ...values, ...mutationVariables })}把表单值提交给 mutation; - 从 useLogin 实现 可以看到,它基于 TanStack Query 的
useMutation封装,内部通过useAuthProviderContext()取出authProvider.login真正执行,并配合useNotification展示成功/失败提示、用useGo处理登录成功后的路由跳转(parsed.params?.to支持?to=回跳参数);
register/forgotPassword/updatePassword页面分别使用useRegister/useForgotPassword/useUpdatePassword,结构完全一致。所有文案均经过useTranslate的pages.login.*、pages.register.*等 i18n key,因此接入国际化后页面文案可整体翻译。
该组件的 UI 行为由 ui-tests 共享用例集 驱动验证(pageLoginTests.bind(this)(LoginPage)),保证各 UI 集成版本的认证页面行为一致。
版本与依赖说明
本文依据的是 refine 文档站3.xx.xx版本的 AuthPage API 文档,示例中使用的包名为@pankod/refine-core、@pankod/refine-antd、@pankod/refine-react-router-v6。当前仓库源码中对应实现位于 packages/antd,导入来源已切换为@refinedev/core,但组件 API、路由接入方式与本文所有 Props 用法保持一致。文档标注该组件支持 Swizzle,可通过 refine CLI 复制源码后深度定制;如只需常规调整,优先使用wrapperProps/contentProps/formProps/renderContent组合即可完成绝大多数视觉与交互定制。
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考