Angular实现手机号输入框格式化(614-123-1234格式)求助
Angular手机号格式化输入框实现方案
要实现XXX-XXX-XXXX格式的手机号输入框,不用jQuery的话,推荐两种纯Angular方案,适配表单控件场景:
方案一:组件内监听表单控件变化
适合单个组件内使用,逻辑直接嵌入组件:
1. 修改输入框模板
把type="number"改成type="text"(数字类型无法显示横杠),移除原生onKeyPress事件:
<input type='text' class="input" formControlName="cel" id="cel" name="cel">
2. 组件类中处理格式化逻辑
通过监听表单控件的valueChanges事件,实时处理输入内容:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'your-component-selector', templateUrl: './your-component.component.html' }) export class YourComponent implements OnInit { form: FormGroup; private lastProcessedValue = ''; constructor(private fb: FormBuilder) { this.form = this.fb.group({ cel: [''] }); } ngOnInit(): void { const phoneControl = this.form.get('cel'); phoneControl?.valueChanges.subscribe(rawValue => { // 只保留输入中的数字 const numericValue = rawValue.replace(/\D/g, ''); // 避免重复处理导致循环 if (numericValue === this.lastProcessedValue.replace(/\D/g, '')) return; // 拼接成XXX-XXX-XXXX格式 let formatted = ''; if (numericValue.length > 0) { formatted += numericValue.slice(0, 3); if (numericValue.length >= 4) { formatted += '-' + numericValue.slice(3, 6); if (numericValue.length >= 7) { formatted += '-' + numericValue.slice(6, 10); } } } this.lastProcessedValue = formatted; // 更新表单值,不触发valueChanges循环 phoneControl.setValue(formatted, { emitEvent: false }); }); } }
方案二:自定义指令(推荐,可复用)
封装成指令后,任何输入框都能直接复用格式化逻辑:
1. 创建手机号掩码指令
import { Directive, HostListener, ElementRef } from '@angular/core'; @Directive({ selector: '[appPhoneMask]' }) export class PhoneMaskDirective { constructor(private el: ElementRef) {} // 监听输入事件,处理格式化 @HostListener('input', ['$event']) onInput(event: Event): void { const input = this.el.nativeElement; const numericValue = input.value.replace(/\D/g, ''); let formatted = ''; if (numericValue.length > 0) { formatted += numericValue.slice(0, 3); if (numericValue.length >= 4) { formatted += '-' + numericValue.slice(3, 6); if (numericValue.length >= 7) { formatted += '-' + numericValue.slice(6, 10); } } } // 保存光标位置,避免格式化后光标跳转到末尾 const start = input.selectionStart; const end = input.selectionEnd; input.value = formatted; // 恢复光标位置 if (start !== null && end !== null) { input.setSelectionRange(start, end); } } // 限制只能输入数字和必要的控制键 @HostListener('keydown', ['$event']) onKeyDown(event: KeyboardEvent): void { const allowedKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab']; const isNumeric = /[0-9]/.test(event.key); if (!isNumeric && !allowedKeys.includes(event.key)) { event.preventDefault(); } } }
2. 在模板中使用指令
同样把输入框改成type="text",添加指令属性:
<input type='text' class="input" formControlName="cel" id="cel" name="cel" appPhoneMask>
额外提示
- 表单提交时,若需要纯数字的手机号,可通过
this.form.get('cel')?.value.replace(/\D/g, '')提取数字部分。 - 指令方案还能扩展支持删除、光标定位等细节,用户体验更好。
内容的提问来源于stack exchange,提问作者Edgar
相关产品推荐
相关产品推荐

