news 2026/9/7 6:05:46

Material UI 登录(Sign-in)模板实战:复用官方模板搭建带主题切换、表单校验与忘记密码流程的登录页

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Material UI 登录(Sign-in)模板实战:复用官方模板搭建带主题切换、表单校验与忘记密码流程的登录页

Material UI 登录(Sign-in)模板实战:复用官方模板搭建带主题切换、表单校验与忘记密码流程的登录页

【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui

本篇指南基于 Material UI 官方仓库中的 Sign-in 模板文档与源码,讲解如何把仓库内置的登录页模板复制到自己的项目中使用,并深入拆解模板中SignIn主组件的表单校验、忘记密码弹窗、共享主题系统(AppTheme+themePrimitives)以及亮色/暗色模式切换的实现原理,帮助你在不手写布局与主题代码的前提下,快速得到一个可运行、可定制的 Material Design 登录页。

模板定位与使用方式

Sign-in 模板属于 Material UI 官方免费 React 模板集的一部分。根据 templates.md 的说明,该模板集包含 Dashboard、Marketing Page、Checkout、Sign-in/Sign-up 和 Blog 等页面,每个模板都提供两套主题(自定义主题与默认 Material Design 2 主题),且均支持亮色/暗色模式;页面各区块通过注释或独立文件划分,可以单独抽取 Hero、Footer 等片段复用到其他页面。

关于 Sign-in 模板的官方使用文档见 README.md,其给出的三步使用流程如下:

  1. sign-inshared-theme两个目录复制到你的项目中,或者复制进仓库自带的示例项目(见 examples 目录下的 Next.js、Vite、Preact、Remix 等示例工程);
  2. 确保项目具备所需依赖:@mui/material@mui/icons-material@emotion/styled@emotion/react
  3. 导入并使用SignIn组件。

其中第 2 步依赖值得注意:@emotion/styled@emotion/reactstyledAPI 和sx属性的运行基础——模板中的CardSignInContainer两个样式化组件(见下文)都依赖@mui/material/stylesstyled

模板文件结构

Sign-in 模板的完整源码位于 sign-in 目录,所有关键文件都有JS 与 TSX 双版本(如SignIn.js/SignIn.tsx),可以按项目的语言栈选择使用。核心结构如下:

sign-in/ ├── SignIn.js / SignIn.tsx # 登录页主组件(入口) ├── components/ │ ├── CustomIcons.js / .tsx # Sitemark、Google、Facebook 内联 SVG 图标 │ └── ForgotPassword.js / .tsx # 忘记密码弹窗 └── ../shared-theme/ # 模板间共享的主题层 ├── AppTheme.js / .tsx # ThemeProvider 封装 ├── themePrimitives.ts / .js # 设计令牌:调色板、字体、形状、阴影 ├── ColorModeSelect.* # 亮/暗/跟随系统切换下拉框 └── customizations/ # 按组件类别拆分的组件级样式 ├── inputs.tsx ├── dataDisplay.tsx ├── feedback.tsx ├── navigation.tsx └── surfaces.ts

从源码结构看,shared-theme被多个模板(blog、checkout、dashboard、sign-in、sign-up、crud-dashboard)共同引用,sign-in/SignIn.tsx第 17~18 行直接import AppTheme from '../shared-theme/AppTheme'ColorModeSelect from '../shared-theme/ColorModeSelect',因此官方文档才要求两个目录一起复制——只复制sign-in而不带shared-theme,相对导入会直接失效。

SignIn 主组件解析

SignIn.tsx 是整个模板的入口组件,签名为SignIn(props: { disableCustomTheme?: boolean })disableCustomTheme属性仅在 MUI 文档站预览时置为true以绕过文档站自身主题,在自己的项目里可以忽略。

布局与样式化容器

组件顶部定义了两个styled组件(SignIn.tsx#L21-L61):

  • Card:基于@mui/material/Card定制,纵向 flex 布局、alignSelf: 'center'水平居中、margin: 'auto'垂直居中;在sm断点以上限宽450pxpaddinggap使用theme.spacing(4)/theme.spacing(2)保持与主题刻度一致;boxShadow使用双层柔和阴影,并通过theme.applyStyles('dark', {...})在暗色模式下换用更深、更重的阴影值;
  • SignInContainer:基于Stack定制,height: 'calc((1 - var(--template-frame-height, 0)) * 100dvh)'配合minHeight: '100%'撑满视口高度,并用::before伪元素铺一层radial-gradient径向渐变背景(暗色模式下切换为深蓝灰渐变),营造登录页常见的“卡片悬浮在渐变背景上”的效果。

--template-frame-height这个 CSS 变量对应主题中cssVarPrefix: 'template'的配置(见下文),默认取0,即容器高度为整个视口。

状态与表单校验

组件用React.useState维护五段状态(SignIn.tsx#L63-L115):emailError/emailErrorMessage/passwordError/passwordErrorMessage以及控制忘记密码弹窗的open。校验逻辑集中在validateInputs

const validateInputs = () => { const email = document.getElementById('email') as HTMLInputElement; const password = document.getElementById('password') as HTMLInputElement; let isValid = true; if (!email.value || !/\S+@\S+\.\S+/.test(email.value)) { setEmailError(true); setEmailErrorMessage('Please enter a valid email address.'); isValid = false; } else { setEmailError(false); setEmailErrorMessage(''); } if (!password.value || password.value.length < 6) { setPasswordError(true); setPasswordErrorMessage('Password must be at least 6 characters long.'); isValid = false; } else { setPasswordError(false); setPasswordErrorMessage(''); } return isValid; };

两条校验规则:邮箱必须匹配正则/\S+@\S+\.\S+/;密码长度至少 6 个字符。提交时handleSubmit会再次检查emailError || passwordError,任一存在则event.preventDefault()拦截提交;校验通过后从FormData中取出emailpassword(模板里仅console.log,实际项目中应在此处接入你的认证后端)。

表单结构与社交登录

渲染部分(SignIn.tsx#L117-L231)组装了完整的登录卡片:

  • <AppTheme>包裹整页,内部第一行是<CssBaseline enableColorScheme />,负责全局样式重置并启用颜色方案(color scheme)切换能力;
  • 右上角固定一个<ColorModeSelect sx={{ position: 'fixed', top: '1rem', right: '1rem' }} />用于切换 System/Light/Dark;
  • 卡片内依次为SitemarkIcon品牌图标、h4标题(字号用clamp(2rem, 10vw, 2.15rem)做流式缩放)、noValidate<form>,内含 Email / Password 两个TextFielderrorhelperText绑定校验状态,autoComplete分别取emailcurrent-password)、"Remember me" 复选框、ForgotPassword弹窗、提交按钮,以及<Divider>or</Divider>分隔线下方的 Google / Facebook 社交登录按钮(模板中为alert占位)和指向注册页的链接。

社交按钮的图标来自 CustomIcons.tsx:SitemarkIconFacebookIconGoogleIcon均为@mui/material/SvgIcon封装的内联 SVG,无需额外图标资源文件即可渲染,也可整体替换成你项目自己的 Logo。

忘记密码弹窗

ForgotPassword.tsx 接收openhandleClose两个属性,主体是一个Dialog,其写法有两个值得学习的点:

  1. 通过slotProps.paper把 Dialog 的 Paper 直接变成<form>(ForgotPassword.tsx#L17-L30):
<Dialog open={open} onClose={handleClose} slotProps={{ paper: { component: 'form', onSubmit: (event: React.SubmitEvent<HTMLFormElement>) => { event.preventDefault(); handleClose(); }, sx: { backgroundImage: 'none' }, }, }} >

这样弹窗内的 "Continue" 按钮可以直接用type="submit"触发表单提交,同时sx: { backgroundImage: 'none' }去掉了 Paper 从主题继承的渐变背景,保持弹窗视觉干净。

  1. 弹窗内含一个autoFocusOutlinedInput(邮箱输入)与DialogActions中的 Cancel / Continue 按钮,"发送邮件重置链接" 的后端调用留给你自行接入。

共享主题系统(shared-theme)

模板视觉一致性的核心在 shared-theme 目录,这部分是模板中最值得借鉴的工程化做法。

AppTheme:主题创建与注入

AppTheme.tsx 用React.useMemo缓存createTheme结果,关键配置为:

createTheme({ cssVariables: { colorSchemeSelector: 'data-mui-color-scheme', cssVarPrefix: 'template', }, colorSchemes, typography, shadows, shape, components: { ...inputsCustomizations, ...dataDisplayCustomizations, ...feedbackCustomizations, ...navigationCustomizations, ...surfacesCustomizations, ...themeComponents, }, });
  • cssVariables将主题的 palette、spacing 等编译为 CSS 变量,前缀为template(即--template-palette-*等),这正是SignInContainer--template-frame-height这类变量命名风格的来源;暗色/亮色切换通过data-mui-color-scheme选择器完成;
  • colorSchemes是 Material UI v6 引入的颜色方案 API,用{ light: {...}, dark: {...} }一次性声明两套色板,配合useColorScheme即可运行时切换;
  • components按类别展开五组组件级定制(inputs、dataDisplay、feedback、navigation、surfaces,分别位于 customizations 目录),把“组件样式”与“基础令牌”分离,便于按需覆盖;
  • 最外层用<ThemeProvider theme={theme} disableTransitionOnChange>渲染,避免切换模式时颜色过渡动画闪烁;当disableCustomTheme为真时直接返回Fragment,不注入主题。

themePrimitives:设计令牌

themePrimitives.ts 是所有颜色的源头,定义了五组 HSL 色阶(brandgraygreenorangered,各含 50~900 十级,见 L33-L96),并导出:

  • colorSchemes(L241-L341):light/dark 两套完整 palette。以 light 为例,primary.mainbrand[400]hsl(210, 98%, 42%))、contrastTextbrand[50];dark 模式将primary.main提升到brand[700]等。每套色板还带一个自定义的baseShadow令牌,并被注入到shadows[1]——shadows数组将默认阴影第一项替换为'var(--template-palette-baseShadow)'(L398-L403),使全局阴影随主题变量联动;
  • typography(L343-L391):Inter, sans-serif字体族,h1 48px/600 字重/1.2 行高,逐档定义至 caption 12px;
  • shape:全局borderRadius: 8
  • getDesignTokens(mode)(L98-L239):旧式的按PaletteMode生成完整 token 的函数,与colorSchemes并存——AppTheme实际使用的是colorSchemes,而getDesignTokens为需要按模式手工取 token 的场景保留。

定制品牌色的最短路径就是改这个文件:例如把brand色阶整体换成你的主色 HSL 值,light/dark 两套colorSchemes.palette.primary会随之全部更新,模板中所有color="primary"的按钮、文字、边框都自动生效,无需逐组件修改。

ColorModeSelect:模式切换控件

ColorModeSelect.tsx 仅 27 行:调用useColorScheme()取得{ mode, setMode },渲染一个Select,选项为System/Light/Dark;若mode为空(即上层未启用 color scheme,如CssBaseline未加enableColorScheme)则返回nullSignIn组件把它fixed在右上角,形成模板预览中“右上角切换主题”的交互。

接入建议与注意事项

  • 复制范围:务必同时复制sign-inshared-theme两个目录,并保持两者的相对位置(shared-themesign-in同级),否则../shared-theme/AppTheme导入会失败。
  • 依赖版本前提:模板使用了 v6 的colorSchemes配置项与slotProps属性(见AppTheme.tsxForgotPassword.tsx),请使用与仓库当前版本一致的@mui/material(v6 及以上);@emotion/react@emotion/styledsx/styled的必需 peer 依赖。
  • 语言选择:每个文件均有.js.tsx双版本,TypeScript 项目中选.tsx版本即可;SignIndisableCustomTheme属性是文档站预览专用,业务项目可忽略。
  • 接入后端:模板中handleSubmit只做console.log,社交按钮只是alert占位,认证接口需自行替换。
  • 横向扩展:同一套shared-theme也被 sign-in-side(带侧边宣传图的登录布局)、sign-up(注册页)等模板复用,按同样的“复制目录 + 导入组件”方式即可组合出风格统一的登录/注册/找回密码整套流程页面。

【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

网盘直链下载助手安装教程:三步提取八大网盘真实下载链接

网盘直链下载助手安装教程&#xff1a;三步提取八大网盘真实下载链接 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…

作者头像 李华
网站建设 2026/9/7 6:04:39

ZStack-CC2530-2.5.1a协议栈全解析:从环境搭建到组网避坑

简介&#xff1a;ZStack-CC2530-2.5.1a.zip 是一套专门针对 TI CC2530 微控制器的 Zigbee 协议栈完整实现&#xff0c;面向物联网、智能家居、工业自动化等低功耗无线网络开发者&#xff0c;可帮助用户从零搭建符合 IEEE 802.15.4 与 Zigbee 标准的无线通信产品。压缩包共收录 …

作者头像 李华
网站建设 2026/9/7 6:01:30

GDAL 3.8.5 + MapServer 8.0.1 Windows x64 部署实战指南

简介&#xff1a;面向Java开发者的GIS开发集成包&#xff0c;基于GDAL 3.8.5与MapServer 8.0.1构建&#xff0c;可在Java环境中直接解析TIFF等栅格文件&#xff0c;并用于Web地图服务与地理空间数据转换&#xff0c;特别适合遥感影像处理与空间分析团队。压缩包共608个文件、约…

作者头像 李华