Vue.js v2.x无插件实现input输入框手机号掩码适配方法
Vue2 + Vuetify 手机号输入掩码实现方案
核心问题说明
不需要将掩码逻辑放在任何生命周期钩子中承载。你之前直接绑定原生DOM事件、手动修改DOM value的写法不符合Vue的响应式设计逻辑,原有掩码的正则处理逻辑可以直接复用,无需重写。
原有写法存在的问题:
- 直接在组件标签上写原生
onkeypress/onblur属性传入DOM实例,会和v-model双向绑定机制冲突,极易出现输入值、视图显示、绑定变量三者不一致的问题 - 手动修改DOM节点的
value属性绕过了Vue的响应式更新链路,后续做表单校验、值提交时会出现异常
实现步骤
- 将原有的
mphone掩码处理函数迁移到Vue实例的methods配置中,核心正则逻辑无需修改 - 移除标签上的原生事件属性,替换为Vuetify组件支持的
@input(输入时触发)、@blur(失焦时触发)事件 - 事件触发时直接处理
v-model绑定的numero响应式变量,不需要手动操作DOM,也不需要setTimeout等DOM更新延迟逻辑,Vue的响应式系统会自动同步输入框显示内容
完整单文件实现代码
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <title>Phone Mask Demo</title> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"> </head> <body> <div id="app"> <v-app> <v-container style="max-width: 500px; margin-top: 50px;"> <v-text-field id="phone" v-model="numero" maxlength="15" label="Número com DDD" :rules="rulesNum" required @input="handleMask" @blur="handleMask" ></v-text-field> </v-container> </v-app> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script> <script> new Vue({ el: '#app', vuetify: new Vuetify(), data() { return { numero: '', rulesNum: [ v => !!v || 'Campo obrigatório', v => v.length >= 14 || 'Número inválido' ] } }, methods: { handleMask() { this.numero = this.mphone(this.numero) }, mphone(valueInput) { if (!valueInput) return '' var regex = valueInput.replace(/\D/g, ""); regex = regex.replace(/^0/, ""); if (regex.length > 10) { regex = regex.replace(/^(\d\d)(\d{5})(\d{4}).*/, "($1) $2-$3"); } else if (regex.length > 5) { regex = regex.replace(/^(\d\d)(\d{4})(\d{0,4}).*/, "($1) $2-$3"); } else if (regex.length > 2) { regex = regex.replace(/(\d)(\d{4})$/,"$1-$2"); } else { regex = regex.replace(/^(\d*)/, "($1"); } return regex; } } }) </script> </body> </html>
补充说明
- 上述代码完全保留了你原来的掩码格式规则,输入时实时格式化,失焦时也会自动修正格式,符合(xx)xxxxx-xxxx的巴西手机号格式要求
- 所有逻辑都在单个HTML文件中,直接打开即可运行,不需要额外构建工具
- 如果不需要实时输入格式化,只需要失焦时再处理格式,移除
@input="handleMask"绑定即可 - 不要在
mounted/created等生命周期里通过document.getElementById获取输入框再绑定事件,Vue框架下通过组件自带的事件绑定即可完成需求,这类手动DOM操作的写法会破坏框架的响应式流程
内容的提问来源于stack exchange,提问作者Amilcar Pio
相关产品推荐
相关产品推荐

