You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular登录页Remember Me功能:实现账号密码联想填充

解决方案

一、修正账号存储逻辑(支持多历史账号)

现有代码仅支持单个账号存储,我们需要调整为历史账号数组存储,确保勾选"Remember Me"的账号能持久化保存,同时支持多账号联想。

1. 调整Component.ts代码

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';

export class JSLoginComponent implements OnInit {
  login!: FormGroup;
  submitted = false;
  id?: string;
  emailPattern = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$";
  loginHistory: Array<{email: string, password: string}> = [];
  filteredHistory: Array<{email: string, password: string}> = [];

  constructor(
    private formBuilder: FormBuilder,
    private dataService: DataService,
    private authService: AuthService,
    private route: ActivatedRoute
  ) {
    if (this.route.snapshot.params["id"]) {
      this.id = this.route.snapshot.params["id"];
    }
  }

  ngOnInit(): void {
    this.login = this.formBuilder.group({
      email: ['', [Validators.required, Validators.pattern(this.emailPattern)]],
      password: ['', Validators.required],
      rememberMe: [false]
    });

    // 加载本地存储的历史账号
    this.loadLoginHistory();

    // 监听邮箱输入,实时过滤匹配的历史账号
    this.login.get('email')?.valueChanges.subscribe(inputValue => {
      this.filteredHistory = this.loginHistory.filter(item => 
        item.email.toLowerCase().includes(inputValue.toLowerCase().trim())
      );
    });
  }

  // 从localStorage加载历史账号列表
  private loadLoginHistory(): void {
    const historyData = localStorage.getItem('loginHistory');
    if (historyData) {
      this.loginHistory = JSON.parse(historyData);
    }
  }

  // 保存/更新历史账号
  private saveToHistory(email: string, password: string): void {
    // 检查账号是否已存在,存在则更新密码,不存在则新增
    const existingIndex = this.loginHistory.findIndex(item => item.email === email);
    if (existingIndex !== -1) {
      this.loginHistory[existingIndex].password = password;
    } else {
      this.loginHistory.push({email, password});
    }
    localStorage.setItem('loginHistory', JSON.stringify(this.loginHistory));
  }

  // 从历史中移除指定账号
  private removeFromHistory(email: string): void {
    this.loginHistory = this.loginHistory.filter(item => item.email !== email);
    localStorage.setItem('loginHistory', JSON.stringify(this.loginHistory));
  }

  onSubmit() {
    this.submitted = true;
    if (this.login.invalid) {
      return;
    }

    const rememberMe = this.login.get('rememberMe')?.value;
    const email = this.login.value.email.trim();
    const password = this.login.value.password;

    // 根据勾选状态处理历史账号
    if (rememberMe) {
      this.saveToHistory(email, password);
    } else {
      this.removeFromHistory(email);
    }

    // 执行登录逻辑
    // this.authService.login(email, password)...
  }

  // 点击历史账号自动填充表单
  fillFormWithHistory(item: {email: string, password: string}): void {
    this.login.patchValue({
      email: item.email,
      password: item.password,
      rememberMe: true
    });
    this.filteredHistory = []; // 填充后隐藏联想列表
  }
}

2. 调整HTML模板(添加账号联想下拉)

<form action="#" [formGroup]="login" (ngSubmit)="onSubmit()" class="login-form">
  <label for="email">Email</label>
  <div class="email-input-wrapper">
    <input 
      type="text" 
      id="email" 
      name="email" 
      formControlName="email" 
      autocomplete="on"
      [ngClass]="{ 'is-invalid': submitted && login.get('email')?.errors }"
    >
    <!-- 历史账号联想列表 -->
    <ul class="email-suggestions" *ngIf="filteredHistory.length > 0 && login.get('email')?.value.trim()">
      <li *ngFor="let item of filteredHistory" (click)="fillFormWithHistory(item)">
        {{ item.email }}
      </li>
    </ul>
  </div>

  <label for="password">Password</label>
  <input 
    type="password" 
    id="password" 
    name="password" 
    formControlName="password"
    [ngClass]="{ 'is-invalid': submitted && login.get('password')?.errors }" 
    (keydown.enter)="onSubmit()"
  >
  
  <div class="loginfoot">
    <div class="loginrememberme">
      <label class="loginremembermelable">
        <input type="checkbox" formControlName="rememberMe">Remember me
        <span class="logincheckbox"></span>
      </label>
    </div>
  </div>
  <div class="loginsubmitbtn">
    <input class="" type="submit" value="Submit">
  </div>
</form>

二、添加联想列表基础样式

在组件CSS文件中加入以下样式,优化联想列表的显示效果:

.email-input-wrapper {
  position: relative;
}

.email-suggestions {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  border: 1px solid #e0e0e0;
  border-top: none;
  background: #ffffff;
  list-style: none;
  padding: 0;
  margin: 0;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  z-index: 100;
}

.email-suggestions li {
  padding: 8px 12px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.email-suggestions li:hover {
  background-color: #f5f5f5;
}

三、核心逻辑说明

  1. 多账号存储:用loginHistory数组存储所有勾选"Remember Me"的账号,持久化到localStorage,支持多账号管理。
  2. 实时联想过滤:监听邮箱输入框内容变化,实时筛选出包含输入内容的历史账号。
  3. 一键填充:点击联想列表中的账号,自动填充邮箱、密码,并自动勾选"Remember Me"。
  4. 账号动态管理:勾选"Remember Me"时添加/更新历史账号,不勾选则从历史列表中移除该账号。

内容的提问来源于stack exchange,提问作者Nani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 10:03:13