React通用登錄/注銷功能實現方案(基于shadcn/ui)

React通用登錄/注銷功能實現方案(基于shadcn/ui)

    • 一、功能需求分析
    • 二、通用功能封裝
      • 1. 通用登錄表單組件
      • 2. 認證Hook封裝
    • 三、功能使用示例
      • 1. 登錄頁面實現
      • 2. 用戶菜單實現
    • 四、路由保護實現
    • 五、方案優勢

一、功能需求分析

需要實現以下核心功能:

  1. 登錄表單組件
  2. 登錄狀態管理
  3. 用戶注銷功能
  4. 路由權限控制

二、通用功能封裝

1. 通用登錄表單組件

// lib/components/auth-form.tsx
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { FormEvent, ReactNode } from "react"interface AuthFormProps {className?: stringtitle: stringdescription?: stringerror?: stringfields: FormField[]submitText?: stringonSubmit: (data: Record<string, string>) => voidchildren?: ReactNode
}export type FormField = {name: stringlabel: stringtype?: stringplaceholder?: stringrequired?: boolean
}export function AuthForm({className,title,description,error,fields,submitText = "Submit",onSubmit,children
}: AuthFormProps) {const handleSubmit = (e: FormEvent<HTMLFormElement>) => {e.preventDefault()const formData = new FormData(e.currentTarget)const data = Object.fromEntries(formData.entries())onSubmit(Object.fromEntries(Object.entries(data).map(([key, value]) => [key, value.toString()])))}return (<div className={cn("flex flex-col gap-6", className)}><Card><CardHeader><CardTitle>{title}</CardTitle>{description && <CardDescription>{description</CardDescription>}</CardHeader><CardContent><form onSubmit={handleSubmit}><div className="flex flex-col gap-6">{error && (<div className="text-sm font-medium text-destructive">{error}</div>)}{fields.map((field) => (<div key={field.name} className="grid gap-3"><Label htmlFor={field.name}>{field.label}</Label><Inputid={field.name}name={field.name}type={field.type || "text"}required={field.required !== false}placeholder={field.placeholder}/></div>))}<Button type="submit" className="w-full">{submitText}</Button></div></form>{children}</CardContent></Card></div>)
}

2. 認證Hook封裝

// lib/hooks/use-auth.ts
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'export const useAuth = () => {const [error, setError] = useState('')const navigate = useNavigate()const login = async (credentials: Record<string, string>) => {try {// 示例驗證邏輯,實際替換為API調用if (credentials.username === 'admin' && credentials.password === '123456') {localStorage.setItem('isAuthenticated', 'true')navigate('/')} else {setError('Invalid credentials')}} catch (err) {setError('Login failed')}}const logout = () => {localStorage.removeItem('isAuthenticated')navigate('/login')}return { login, logout, error }
}

三、功能使用示例

1. 登錄頁面實現

// app/login/page.tsx
import { AuthForm } from "@/lib/components/auth-form"
import { useAuth } from "@/lib/hooks/use-auth"export default function LoginPage() {const { login, error } = useAuth()const loginFields = [{ name: "username", label: "Username", required: true },{ name: "password", label: "Password", type: "password", required: true }]return (<div className="flex h-screen items-center justify-center bg-gray-100 p-4"><div className="w-full max-w-md"><AuthFormtitle="Login to System"description="Enter your credentials to continue"fields={loginFields}onSubmit={login}error={error}submitText="Sign In"/></div></div>)
}

2. 用戶菜單實現

// components/nav-user.tsx
import { useAuth } from "@/lib/hooks/use-auth"export function NavUser() {const { logout } = useAuth()return (<DropdownMenu>{/* 其他菜單項 */}<DropdownMenuItem onClick={logout}><LogOut />Log out</DropdownMenuItem></DropdownMenu>)
}

四、路由保護實現

// router.ts
import { Navigate } from 'react-router-dom'const PrivateRoute = ({ children }: { children: JSX.Element }) => {const isAuthenticated = localStorage.getItem('isAuthenticated')return isAuthenticated ? children : <Navigate to="/login" replace />
}

五、方案優勢

  1. 高度可配置:表單字段、驗證邏輯均可自定義
  2. 類型安全:完善的TypeScript類型定義
  3. UI解耦:業務邏輯與UI組件分離
  4. 易于擴展:支持添加注冊/找回密碼等衍生功能

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70385.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70385.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70385.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jEasyUI 創建學校課程表

jEasyUI 創建學校課程表 引言 隨著信息技術的飛速發展,教育行業也迎來了數字化轉型的浪潮。學校課程表的創建和管理作為教育信息化的重要組成部分,其效率和準確性直接影響到學校的教學秩序。jEasyUI,作為一款優秀的開源UI框架,憑借其易用性、靈活性和豐富的組件,成為了許…

Linux 內核中的 container_of 宏:以 ipoib_rx_poll_rss 函數為例

在 Linux 內核編程中,container_of 是一個非常實用的宏,主要用于通過結構體的成員指針來獲取包含該成員的整個結構體的指針。rx_ring = container_of(napi, struct ipoib_recv_ring, napi); 在代碼中就是利用了這個宏,下面我們詳細分析它的作用和工作原理。 背景知識 在內…

【論文學習】RVS-FDSC:一種基于四方向條帶卷積的視網膜血管分割方法以增強特征提取

寫在前面&#xff1a;本博客僅作記錄學習之用&#xff0c;部分圖片來自網絡&#xff0c;如需引用請注明出處&#xff0c;同時如有侵犯您的權益&#xff0c;請聯系刪除&#xff01; 文章目錄 前言論文論文內容RSC模塊MSPF2 模塊RPDA模塊 實驗效果 總結互動致謝參考往期回顧 前言…

藍橋杯篇---IAP15F2K61S2矩陣鍵盤

文章目錄 前言簡介矩陣鍵盤的工作原理1.行掃描2.檢測列狀態3.按鍵識別 硬件連接1.行線2.列線 矩陣鍵盤使用步驟1.初始化IO口2.掃描鍵盤3.消抖處理4.按鍵識別 示例代碼&#xff1a;4x4矩陣鍵盤掃描示例代碼&#xff1a;優化后的矩陣鍵盤掃描注意事項1.消抖處理2.掃描頻率3.IO口配…

【ISO 14229-1:2023 UDS診斷(ECU復位0x11服務)測試用例CAPL代碼全解析?】

ISO 14229-1:2023 UDS診斷【ECU復位0x11服務】_TestCase19 作者&#xff1a;車端域控測試工程師 更新日期&#xff1a;2025年02月19日 關鍵詞&#xff1a;UDS診斷協議、ECU復位服務、0x11服務、ISO 14229-1:2023 TC11-019測試用例 用例ID測試場景驗證要點參考條款預期結果TC…

Vue 3 30天精進之旅:Day 29 - 項目實戰

在學習了近一個月的Vue 3知識后&#xff0c;今天是我們學習旅程的第29天。在這一天&#xff0c;我們將專注于實踐&#xff0c;通過一個小型項目來鞏固之前的學習成果&#xff0c;并為之后的展示做好準備。 一、項目目標 我們將構建一個簡單的個人博客應用&#xff0c;具備以下…

Windows Docker運行Implicit-SVSDF-Planner

Windows Docker運行GitHub - ZJU-FAST-Lab/Implicit-SVSDF-Planner: [SIGGRAPH 2024 & TOG] 1. 設置環境 我將項目git clone在D:/Github目錄中。 下載ubuntu20.04 noetic鏡像 docker pull osrf/ros:noetic-desktop-full-focal 啟動容器&#xff0c;掛載主機的D:/Github文…

PHP 安全與加密:守護 Web 應用的基石

PHP 學習資料 PHP 學習資料 PHP 學習資料 在當今數字化時代&#xff0c;Web 應用無處不在&#xff0c;而 PHP 作為一種廣泛使用的服務器端腳本語言&#xff0c;承載著無數網站和應用的核心邏輯。然而&#xff0c;隨著網絡攻擊手段日益復雜&#xff0c;PHP 應用面臨著諸多安全…

Qt中使用QPdfWriter類結合QPainter類繪制并輸出PDF文件

一.類的介紹 1.QPdfWriter介紹 Qt中提供了一個直接可以處理PDF的類&#xff0c;這就是QPdfWriter類。 &#xff08;1&#xff09;PDF文件生成 支持創建新的PDF文件或覆蓋已有文件&#xff0c;通過構造函數直接綁定文件路徑或QFile對象&#xff1b; 默認生成矢量圖形PDF&#…

Golang GORM系列:GORM無縫集成web框架

高效的數據管理是每個成功的web應用程序的支柱。GORM是通用的Go對象關系映射庫&#xff0c;它與流行的Go web框架搭配得非常好&#xff0c;提供了無縫集成&#xff0c;簡化了數據交互。本指南將帶你探索GORM和web框架&#xff08;如Gin&#xff0c; Echo和Beego&#xff09;之間…

SAM C++ TensorRT(實時圖像分割)

SPEED SAM C TENSORRT &#x1f310; 1、概述 用于SAM&#xff08;segment anything model分割一切模型&#xff09;的TensorRT和CUDA優化的高表現C實現&#xff0c;特別適用于實時圖像分割任務。 &#x1f4e2; 更新 模型轉換&#xff1a;從ONNX模型構建TensorRT引擎以加速…

【LLAMA】羊駝從LLAMA1到LLAMA3梳理

every blog every motto: Although the world is full of suffering&#xff0c; it is full also of the overcoming of it 0. 前言 LLAMA 1到3梳理 1. LLAMA 1 論文&#xff1a; LLaMA: Open and Efficient Foundation Language Models 時間&#xff1a; 2023.02 1.1 前言…

什么是網絡安全?網絡安全防范技術包括哪些?

伴隨著互聯網的發展&#xff0c;它已經成為我們生活中不可或缺的存在&#xff0c;無論是個人還是企業&#xff0c;都離不開互聯網。正因為互聯網得到了重視&#xff0c;網絡安全問題也隨之加劇&#xff0c;給我們的信息安全造成嚴重威脅&#xff0c;而想要有效規避這些風險&…

【從0做項目】Java搜索引擎(7) web模塊

阿華代碼&#xff0c;不是逆風&#xff0c;就是我瘋 你們的點贊收藏是我前進最大的動力&#xff01;&#xff01; 希望本文內容能夠幫助到你&#xff01;&#xff01; 目錄 文章導讀 零&#xff1a;項目結果展示 一&#xff1a;后端web模塊 1&#xff1a;思路 2&#xff1a…

Visual Studio Code 集成 Baidu Comate

文章目錄 安裝Baidu Comate插件 安裝Baidu Comate插件 從左主側欄中 點擊 【擴展】這個圖標&#xff0c;然后在上方輸入欄中輸入 baidu comate —>選中列出的Bai Comate —>點擊 【安裝】按鈕&#xff0c;等待安裝完畢…

WeMos D1+PIR+Android 的小場景制作

最近在做一個有趣的小場景功能&#xff0c;其實已經有成熟產品&#xff0c;但是考慮到沒法實現場景擴展&#xff0c;所以自己開始動手做。 場景描述&#xff1a;玄關人體感應&#xff0c;有人進門&#xff0c;致歡迎詞&#xff0c;有人離開&#xff0c;致歡送詞。 硬件設備&a…

Android ListPreference使用

Android ListPreference使用 參考 添加鏈接描述 導入 androidx.preference.ListPreferenceListPreference是Android中的一個Preference子類,用于顯示一個可選擇的列表,并且可以保存用戶所選擇的值。它繼承自DialogPreference,可以在用戶點擊時彈出一個對話框,顯示可選擇的…

Spring Security實現記住我功能的實戰指南

在現代Web應用中&#xff0c;"記住我"功能是提升用戶體驗的重要特性之一。用戶無需在每次訪問時重新登錄&#xff0c;這不僅方便&#xff0c;還能增強用戶對應用的粘性。今天&#xff0c;我們將通過一個具體的實例&#xff0c;詳細探討如何在Spring Security中實現&q…

用命令模式設計一個JSBridge用于JavaScript與Android交互通信

用命令模式設計一個JSBridge用于JavaScript與Android交互通信 在開發APP的過程中&#xff0c;通常會遇到Android需要與H5頁面互相傳遞數據的情況&#xff0c;而Android與H5交互的容器就是WebView。 因此要想設計一個高可用的 J S B r i d g e JSBridge JSBridge&#xff0c;不…

ModuleNotFoundError: No module named ‘timm.optim.novogr兩種解決方法

運行報錯 from timm.optim.novograd import NovoGradModuleNotFoundError: No module named ‘timm.optim.novograd’。 問題原因 timm版本過高&#xff0c;novograd函數已被拋棄。 解決辦法 方法1&#xff1a;安裝更低版本的timm pip install timm0.4.12方法2&#xff1a…