如何用Bootstrap 5.2与Angular 14实现右上角Toast通知及自定义服务
Angular 14 自定义Toast通知实现方案
方案一:基于Bootstrap 5.2实现
1. 安装依赖
首先安装Bootstrap:
npm install bootstrap
在angular.json的styles数组中添加Bootstrap CSS:
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css" ]
2. 创建独立Toast组件
生成一个独立组件:
ng generate component toast --standalone
toast.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-toast', standalone: true, imports: [CommonModule], templateUrl: './toast.component.html', styleUrls: ['./toast.component.css'] }) export class ToastComponent { @Input() title!: string; @Input() message!: string; @Input() type!: 'success' | 'warning' | 'error' | 'info'; @Output() close = new EventEmitter<void>(); dismiss() { this.close.emit(); } }
toast.component.html
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true" [ngClass]="type"> <div class="toast-header"> <strong class="me-auto">{{ title }}</strong> <button type="button" class="btn-close" aria-label="Close" (click)="dismiss()"></button> </div> <div class="toast-body"> {{ message }} </div> </div>
toast.component.css
.toast { margin-bottom: 1rem; min-width: 300px; } .toast.success .toast-header { background-color: #d1e7dd; color: #0f5132; border-bottom: 1px solid #badbcc; } .toast.warning .toast-header { background-color: #fff3cd; color: #856404; border-bottom: 1px solid #ffeaa7; } .toast.error .toast-header { background-color: #f8d7da; color: #721c24; border-bottom: 1px solid #f5c6cb; } .toast.info .toast-header { background-color: #d1ecf1; color: #0c5460; border-bottom: 1px solid #bee5eb; }
3. 创建Toast服务
生成服务:
ng generate service toast
toast.service.ts
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; export interface Toast { id: string; title: string; message: string; type: 'success' | 'warning' | 'error' | 'info'; } @Injectable({ providedIn: 'root' }) export class ToastService { private toastsSubject = new BehaviorSubject<Toast[]>([]); toasts$ = this.toastsSubject.asObservable(); constructor() { } private addToast(title: string, message: string, type: 'success' | 'warning' | 'error' | 'info') { const id = Math.random().toString(36).substring(2, 15); const toast: Toast = { id, title, message, type }; this.toastsSubject.next([...this.toastsSubject.value, toast]); // 5秒后自动关闭 setTimeout(() => this.removeToast(id), 5000); } showSuccessToast(title: string, message: string) { this.addToast(title, message, 'success'); } showWarningToast(title: string, message: string) { this.addToast(title, message, 'warning'); } showErrorToast(title: string, message: string) { this.addToast(title, message, 'error'); } showInfoToast(title: string, message: string) { this.addToast(title, message, 'info'); } removeToast(id: string) { this.toastsSubject.next(this.toastsSubject.value.filter(toast => toast.id !== id)); } }
4. 添加Toast容器到根组件
在app.component.html中添加Toast容器:
<div class="toast-container position-fixed top-0 end-0 p-3"> <app-toast *ngFor="let toast of toasts$ | async" [title]="toast.title" [message]="toast.message" [type]="toast.type" (close)="toastService.removeToast(toast.id)" ></app-toast> </div> <!-- 示例按钮 --> <button class="btn btn-success" (click)="showSuccess()">显示成功Toast</button> <button class="btn btn-warning" (click)="showWarning()">显示警告Toast</button> <button class="btn btn-danger" (click)="showError()">显示错误Toast</button> <button class="btn btn-info" (click)="showInfo()">显示信息Toast</button>
在app.component.ts中导入必要模块和服务:
import { Component } from '@angular/core'; import { ToastComponent } from './toast/toast.component'; import { ToastService } from './toast.service'; import { AsyncPipe } from '@angular/common'; @Component({ selector: 'app-root', standalone: true, imports: [ToastComponent, AsyncPipe], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { toasts$ = this.toastService.toasts$; constructor(public toastService: ToastService) { } showSuccess() { this.toastService.showSuccessToast('Success toast title', 'This is a success toast message.'); } showWarning() { this.toastService.showWarningToast('Warning toast title', 'This is a warning toast message.'); } showError() { this.toastService.showErrorToast('Error toast title', 'This is an error toast message.'); } showInfo() { this.toastService.showInfoToast('Info toast title', 'This is an info toast message.'); } }
方案二:纯自定义实现(无需Bootstrap)
如果不想依赖Bootstrap,只需修改Toast组件的HTML和CSS:
修改toast.component.html
<div class="toast" [ngClass]="type"> <div class="toast-header"> <strong class="me-auto">{{ title }}</strong> <button type="button" class="btn-close" aria-label="Close" (click)="dismiss()">×</button> </div> <div class="toast-body"> {{ message }} </div> </div>
修改toast.component.css
.toast { position: relative; padding: 1rem; margin-bottom: 1rem; border-radius: 0.25rem; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); min-width: 300px; } .toast-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem; padding-bottom: 0.5rem; border-bottom: 1px solid rgba(0, 0, 0, 0.1); } .btn-close { background: none; border: none; font-size: 1.25rem; cursor: pointer; padding: 0; line-height: 1; color: inherit; } .toast.success { background-color: #d1e7dd; color: #0f5132; border-left: 4px solid #198754; } .toast.warning { background-color: #fff3cd; color: #856404; border-left: 4px solid #ffc107; } .toast.error { background-color: #f8d7da; color: #721c24; border-left: 4px solid #dc3545; } .toast.info { background-color: #d1ecf1; color: #0c5460; border-left: 4px solid #0dcaf0; }
修改app.component.html中的容器
<div class="toast-container"> <app-toast *ngFor="let toast of toasts$ | async" [title]="toast.title" [message]="toast.message" [type]="toast.type" (close)="toastService.removeToast(toast.id)" ></app-toast> </div> <!-- 示例按钮 --> <button (click)="showSuccess()">显示成功Toast</button> <button (click)="showWarning()">显示警告Toast</button> <button (click)="showError()">显示错误Toast</button> <button (click)="showInfo()">显示信息Toast</button>
添加容器样式到app.component.css
.toast-container { position: fixed; top: 1rem; right: 1rem; z-index: 1050; }
使用说明
在任意组件中,只需注入ToastService即可调用对应的方法显示Toast:
import { ToastService } from './toast.service'; constructor(private toastService: ToastService) { } // 示例调用 showSuccess() { this.toastService.showSuccessToast('操作成功', '数据已保存'); }
内容的提问来源于stack exchange,提问作者Atique Ahmed
相关产品推荐
相关产品推荐

