news 2026/9/13 23:38:19

refine Ant Design `<AuthPage>` 组件实战:登录、注册与密码重置页的类型、Props 与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
refine Ant Design `<AuthPage>` 组件实战:登录、注册与密码重置页的类型、Props 与源码解析

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忘记密码页email
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
  • registerforgotPasswordupdatePassword三种类型需要通过routes自行声明路径(文档示例分别使用/register/forgot-password/update-password)。

四种类型详解

Login(默认)

登录页提交表单后,会调用authProviderlogin方法并传入表单值:

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类型用于用户已登录场景下修改密码。从源码看,该表单包含passwordconfirmPassword两个字段,后者通过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

仅对loginregister两种类型可用。

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.onFinishformValues中读到。从源码看,默认实现的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

仅对registerforgotPassword类型可用。

定义“去登录”的链接节点,也可以传任意 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> ); }} /> )}

hideFormtitlemutationVariables(补充)

在 core 包的 AuthPageProps 类型定义 中还能看到三个 Props 文档:

  • hideForm?: boolean—— 隐藏表单主体,只保留 provider 按钮与链接,适合纯 OAuth 登录页;
  • title?: React.ReactNode—— 替换卡片上方的页面标题,设为false则完全不渲染;
  • mutationVariables?: Record<string, any>—— 额外变量,会与表单值一起合并传给authProvider的对应方法。

API Reference

Properties

PropertyTypeDefault
typelogin|register|forgotPassword|updatePasswordlogin
providersOAuthProvider[]-
registerLinkReact.ReactNode指向/register的链接
forgotPasswordLinkReact.ReactNode指向/forgot-password的链接
loginLinkReact.ReactNode指向/login的链接
rememberMeReact.ReactNode<Checkbox>Remember me</Checkbox>
hideFormboolean-
wrapperPropsLayoutProps(antd)-
contentPropsCardProps(antd)-
formPropsFormProps(antd)-
renderContent(content: ReactNode, title: ReactNode) => ReactNode-
titleReact.ReactNode-

Interface

interface OAuthProvider { name: string; icon?: React.ReactNode; label?: string; }

表单提交到 authProvider 的源码级调用链

四种页面共用同一套机制,以登录为例:

  1. LoginPage内部通过 core 的useLogin获取 mutation:const { mutate: login, isPending } = useLogin<LoginFormTypes>()
  2. antdFormonFinish={(values) => login({ ...values, ...mutationVariables })}把表单值提交给 mutation;
  3. 从 useLogin 实现 可以看到,它基于 TanStack Query 的useMutation封装,内部通过useAuthProviderContext()取出authProvider.login真正执行,并配合useNotification展示成功/失败提示、用useGo处理登录成功后的路由跳转(parsed.params?.to支持?to=回跳参数);

register/forgotPassword/updatePassword页面分别使用useRegister/useForgotPassword/useUpdatePassword,结构完全一致。所有文案均经过useTranslatepages.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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 23:34:28

专利权利要求书怎么写:说明书依据与修改超范围风险

审查意见来了&#xff0c;说你的权利要求没有创造性。你赶紧从说明书里找一个技术特征加到权利要求里——这个特征说明书里提到了&#xff0c;但原权利要求书里没写。改完提交了&#xff0c;授权了。几年后竞争对手拿你的专利去提无效宣告&#xff0c;理由是&#xff1a;你当年…

作者头像 李华