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

Angular导航栏、侧边栏与路由问题:登录页需单独显示

问题解决:Angular 登录页与Menu组件同时显示的问题

核心问题分析

你当前的问题是因为 app.component.html 直接固定渲染了 <app-menu></app-menu>,导致无论路由跳转到哪个页面,Menu组件的侧边栏、导航栏都会一直显示,登录页被渲染在Menu内部的 <router-outlet> 中,所以两者同时出现。要实现「首次加载仅显示登录页,登录后显示Menu并正常路由」,需要区分未登录/已登录两种布局。


解决方案步骤

1. 创建登录状态管理服务

先实现一个简单的AuthService来管理登录状态(实际项目中可结合后端接口优化):

// auth.service.ts
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  // 判断是否已登录(示例用localStorage存储token)
  isLoggedIn(): boolean {
    return !!localStorage.getItem('authToken');
  }

  // 登录时存储token
  login(token: string): void {
    localStorage.setItem('authToken', token);
  }

  // 登出时清除token
  logout(): void {
    localStorage.removeItem('authToken');
  }
}

2. 修改App组件的布局切换逻辑

修改 app.component.html,根据登录状态切换显示内容:

<!-- app.component.html -->
<!-- 已登录时显示Menu布局 -->
<app-menu *ngIf="authService.isLoggedIn()"></app-menu>
<!-- 未登录时直接渲染登录页(使用根路由出口) -->
<router-outlet *ngIf="!authService.isLoggedIn()"></router-outlet>

在 app.component.ts 中注入AuthService:

// app.component.ts
import { Component } from '@angular/core';
import { AuthService } from './auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(public authService: AuthService) {}
}

3. 完善Login组件的登录逻辑

修改Login组件,登录成功后更新状态并跳转到权限页面:

// login.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthService } from '../auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  loginform1!: FormGroup;

  constructor(
    private fb: FormBuilder,
    private authService: AuthService,
    private router: Router
  ) {}

  ngOnInit(): void {
    this.loginform1 = this.fb.group({
      Uname: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  // 获取表单控件
  get Uname() { return this.loginform1.get('Uname'); }
  get password() { return this.loginform1.get('password'); }

  // 登录处理
  loginUser(): void {
    if (this.loginform1.valid) {
      // 此处替换为实际后端登录请求,示例用模拟token
      const mockToken = 'user-auth-token';
      this.authService.login(mockToken);
      // 登录成功后跳转到首页(比如header组件)
      this.router.navigate(['/header']);
    }
  }

  submit(): void {
    this.loginUser();
  }
}

同时移除Login组件模板中的多余<body>标签(Angular组件模板不能包含body):

<!-- login.component.html 修改后 -->
<form [formGroup]="loginform1" (ngSubmit)="loginUser()">
    <div class="login-container">
        <h2 class="lg">Login Page</h2>
        <label>User Name</label>
        <input type="text" name="Uname" id="Uname"  placeholder="Username" formControlName="Uname">
        <span style="color: red;" *ngIf="Uname && Uname.invalid && Uname.touched" >this field is required.</span>
        <br><br>
        <label>Password</label>
        <input type="password" name="password" id="Pass"  placeholder="Password" formControlName="password">
        <span style="color: red;" *ngIf="password && password.invalid && password.touched" >this field is required.</span>
        <br>
        <a href="#" style="color: white;">Forgot Password</a><br><br>
        <button class="bt" (click)="submit()" [disabled]="loginform1.invalid">Login</button> <br><br>
        <input type="checkbox" id="check">
        <span>Remember me</span><br>
        <button type="button" class="btn btn-primary" routerLink="/dashboard">Register</button>
        <br><br>
    </div>
</form>

4. 优化Menu组件的路由链接

将Menu组件中的相对路由改为绝对路径(避免路由层级问题):

<!-- Menu组件中示例修改 -->
<button routerLink="/header" mat-button>home</button>
<button routerLink="/home" mat-button><mat-icon>home</mat-icon> Pages</button>

5. 可选:添加路由守卫保护权限页面

为了防止未登录用户直接访问header、home等页面,添加路由守卫:

// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.authService.isLoggedIn()) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }
}

修改路由配置,给需要权限的路由添加守卫:

// app.routing.ts
import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { Headers } from './header/header.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './auth.guard';

export const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent },
  { path: 'header', component: Headers, canActivate: [AuthGuard] },
  { path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
  { path: '', redirectTo: '/login', pathMatch: 'full' },
];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:49:52