angular登录页

news/2025/2/25 14:05:01

说明:登录 login+dialog
效果图:

step1:

javascript">import { Component } from '@angular/core';
import {FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { AlertDialogComponent } from './alert-dialog.component';
import {NgIf} from '@angular/common';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  imports: [
    FormsModule,
    NgIf,
    ReactiveFormsModule
  ],
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  loginForm = new FormGroup({
    username: new FormControl('', [
      Validators.required,
      Validators.minLength(3)
    ]),
    password: new FormControl('', [
      Validators.required,
      Validators.minLength(6)
    ])
  });

  constructor(private dialog: MatDialog) {}

  get username() { return this.loginForm.get('username'); }
  get password() { return this.loginForm.get('password'); }

  onSubmit() {
    if (this.loginForm.invalid) return;

    const { username, password } = this.loginForm.value;

    if (username === 'admin' && password === '123456') {
      this.showAlert('登录成功', 'success');
      this.loginForm.reset();
    } else {
      this.showAlert('用户名或密码错误', 'error');
    }
  }

  private showAlert(message: string, type: 'success' | 'error') {
    this.dialog.open(AlertDialogComponent, {
      data: { message, type },
      width: '300px'
    });
  }
}

step2:

<form [formGroup]="loginForm" (ngSubmit)="onSubmit()" class="login-form">
  <h2>用户登录</h2>

  <div class="form-group">
    <label for="username">用户名</label>
    <input
      type="text"
      id="username"
      formControlName="username"
      placeholder="至少3个字符"
      [class.invalid]="username?.invalid"
    >
    <div class="error-message" *ngIf="username?.errors?.['required'] && username?.touched">
      用户名不能为空
    </div>
    <div class="error-message" *ngIf="username?.errors?.['minlength'] && username?.touched">
      用户名至少3个字符
    </div>
  </div>

  <div class="form-group">
    <label for="password">密码</label>
    <input
      type="password"
      id="password"
      formControlName="password"
      placeholder="至少6位密码"
      [class.invalid]="password?.invalid"
    >
    <div class="error-message" *ngIf="password?.errors?.['required'] && password?.touched">
      密码不能为空
    </div>
    <div class="error-message" *ngIf="password?.errors?.['minlength'] && password?.touched">
      密码至少6个字符
    </div>
  </div>

  <button
    type="submit"
    class="submit-btn"
    [disabled]="loginForm.invalid"
  >
    立即登录
  </button>
</form>

step3:

.login-form {
  max-width: 300px;
  margin: 0 auto;
  padding: 20px;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
}

.form-group input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.form-group input.invalid {
  border-color: #dc3545;
}

.error-message {
  color: #dc3545;
  font-size: 0.875rem;
  margin-top: 4px;
}

.submit-btn {
  width: 100%;
  padding: 10px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.submit-btn:hover {
  background-color: #0056b3;
}

step4:

javascript">import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { NgClass } from '@angular/common';
import {MatButton} from "@angular/material/button";

@Component({
  selector: 'app-alert-dialog',
  standalone: true,
  imports: [MatDialogModule, NgClass, MatButton],
  templateUrl: './alert-dialog.component.html',
  styleUrls: ['./alert-dialog.component.css']
})
export class AlertDialogComponent {
  constructor(
    @Inject(MAT_DIALOG_DATA) public data: { message: string; type: 'success' | 'error' },
    public dialogRef: MatDialogRef<AlertDialogComponent>
  ) {}
}

step5:

<div class="alert-dialog" [ngClass]="data.type">
  <div class="alert-content">
    <h3 class="alert-title">
      <span class="alert-icon">  {{ data.type === 'success' ? '✅' : '❌' }} {{ data.message }} </span>
    </h3>
    <div class="action-buttons">
      <button mat-button class="alert-action" (click)="dialogRef.close()">
        确定
      </button>
    </div>
  </div>
</div>

step6:

.alert-dialog {
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 24px;
  background: #fff;
  margin: 0 16px;
}

.alert-title {
  margin: 0 0 16px 0;
  font-size: 18px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.87);
}

.alert-icon {
  margin-right: 8px;
  font-size: 20px;
}

.action-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.alert-action {
  border-radius: 8px !important;
  padding: 8px 16px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  transition: all 0.3s ease;
}

.alert-dialog[ng-reflect-ng-class="success"] {
  background: #e8f5e9;
}

.alert-dialog[ng-reflect-ng-class="success"] .alert-title,
.alert-dialog[ng-reflect-ng-class="success"] .alert-action {
  color: #2e7d32;
}

.alert-dialog[ng-reflect-ng-class="error"] {
  background: #ffebee;
}

.alert-dialog[ng-reflect-ng-class="error"] .alert-title,
.alert-dialog[ng-reflect-ng-class="error"] .alert-action {
  color: #c62828;
}

end


http://www.niftyadmin.cn/n/5865582.html

相关文章

FFmpeg进化论:从av_register_all手动注册到编译期自动加载的技术跃迁

介绍 音视频开发都知道 FFmpeg,因此对 av_register_all 这个 API 都很熟悉,但ffmpeg 4.0 版本开始就已经废弃了,是旧版本中用于全局初始化的重要接口。 基本功能 核心作用:av_register_all() 用于注册所有封装器(muxer)、解封装器(demuxer)和协议处理器(protocol),…

什么是 OCP 数据库专家

OCP 即 Oracle Certified Professional&#xff0c;Oracle 认证专业人员&#xff0c;代表持证人在 Oracle 数据库领域具备专业的技能和知识。获得 OCP 数据库专家认证意味着你在 Oracle 数据库管理、开发、优化等方面达到了较高的水平&#xff0c;能够独立承担复杂的数据库相关…

**模式的好处 (设计模式)

what’s up !? 这样整理下发现更容易理解设计模式了 学习嘛&#xff0c;就是拿着 rua 横着rua 竖着rua 前面rua 后面rua 【’ _ ’ 】 目录 简单工厂模式工厂模式抽象工厂模式单例模式建造者模式原型模式代理模式适配器 模式桥梁 模式装饰 模式门面 模式 &#xff08;也叫 外…

前端(layui表单对应行颜色、登陆页面、轮播)

1&#xff1a;动态获取数据根据数据的不同改变对应行颜色&#xff08;JavaScript&#xff09; done: function (res, curr, count) {console.log(res);// 检查返回的数据是否包含code字段&#xff0c;并且code为0if (res.code "0") {// 数据加载成功console.log(…

免费PDF工具

Smallpdf.com - A Free Solution to all your PDF Problems Smallpdf - the platform that makes it super easy to convert and edit all your PDF files. Solving all your PDF problems in one place - and yes, free. https://smallpdf.com/#rappSmallpdf.com-解决您所有PD…

Postman操作(接口测试、生成测试报告、MockServer等)

文章目录 前言Postman简介Postman下载和安装下载安装注册与登录 Postman工具介绍界面说明发送第一个请求1. 创建一个工程目录2. 创建collection合集3. 创建一个接口请求4. 输入接口请求参数5. 发送请求 CollectionFolderRequset请求基础功能响应 全局变量、集合变量、环境变量全…

字符型验证码自动识别与填充提交——OCR浏览器插件的完整实现

【创作不易&#xff0c;切勿抄袭&#xff0c;转载请注明出处&#xff0c;侵权必究】 本文概览 本文结合开源的tesseract OCR库共尝试三种方法实现了字符型验证码识别与填充提交浏览器插件&#xff08;非通用型&#xff0c;具体得根据自己网页内容改造&#xff0c;可借鉴本文方…

解决VMware 安装 Ubuntu 后无法全屏的问题

根据以往的经验&#xff0c;一直想安装 VMware-tools&#xff0c;但是看了官方介绍才突然发现早就已经有更好的替代品了。 官方介绍连接在此&#xff1a;Install VMware Tools in VMware products 如上图所述&#xff0c;早期的 Linux 系统推荐安装 VMware-tools&#xff0c;但…