vue 只能让用户输入字母和数字,不允许其他特殊字符

该博客介绍了一个使用Vue.js实现的密码输入验证功能,通过监听用户输入并使用正则表达式检测特殊字符。当用户输入的密码超过10个字符或包含特殊字符时,系统会提示用户重新输入,确保密码只包含数字和字母。

使用replace清除字符串中的特殊字符,如果清除了,长度发生了变化,就判断用户输入包含特殊字符串,进而清空输入框,并提示用户。

<div id="baba">
        请输入密码:<input type="password" v-model.lazy="userInfo.userPwd" placeholder="长度不得大于10,必须是数字和字母">
    </div>
    <script>
        new Vue({
            el: '#baba',
            data() {
                return {
                    userInfo: {
                        userPwd: '',
                    }
                }
            },
            watch: {
                "userInfo.userPwd": function (newVal, oldVal) {
                    console.log("新值", newVal);
                    console.log("旧值", oldVal);
                    if (newVal.length > 10) {
                        alert("密码过长请重新设置");
                    }else if (newVal.length != newVal.replace(/[^\w]/g, '').length) {
                        //replace就是清除的意思,判断清除特殊字符串后,如果长度和没有清除之前保持一致
                        //那就代表有特殊字符串,就执行这个if代码块
                        alert("只能为数字和字母");
                        this.userInfo.userPwd='';
                    }
                }
            },
        })
    </script>

<think> 我们被要求控制el-input密码输入只能输入大小写字母数字特殊字符特殊字符通常指的是键盘上可见的标点符号等,例如:!@#$%^&*()_+-=[]{}|;:&#39;",.<>/? 根据引用中提供的方法,我们可以使用正则表达式来限制输入。常见的做法是在输入框上使用oninput或onkeyup事件,通过替换非允许字符为空字符串来实现。 我们需要的正则表达式应该匹配除了大小写字母数字特殊字符之外的所有字符,并将其替换为空。 定义允许字符集: 大小写字母:a-z A-Z 数字:0-9 特殊字符:这里我们需要明确哪些特殊字符,但通常密码允许特殊字符包括:!@#$%^&*()_+-=[]{}|;:&#39;",.<>/? 等(注意:有些字符在正则表达式中需要转义) 因此,我们可以构建正则表达式:/[^a-zA-Z0-9!@#$%^&*()_+\-=\[\]{}|;:&#39;",.<>/?]/g 注意: 1. 在正则表达式中,特殊字符如:-、[、]、^等需要转义,但在字符集[]中,有些字符需要转义,有些则需要。为了安全,我们可以将特殊字符放在[]中,并对需要转义的字符进行转义。 2. 由于特殊字符较多,且同场景允许特殊字符可能同,这里我们假设允许常见的键盘上可输入特殊字符包括空格)。 但是,在正则表达式中,我们可以这样写:/[^a-zA-Z0-9!@#$%^&*()_+\-=\[\]{}|\\;:&#39;",.<>/?]/g 但是注意:在字符集中,有些字符需要转义,比如@、#、$、%、&等,但为了安全,我们可以将字符集内的特殊字符进行转义(除了那些在字符集中有特殊意义的字符,如^、-、]等)。实际上,在字符集中,只有以下几个字符需要转义:^、-、]、\。其他字符字符集中都是字面意义。 我们构建正则表达式:/[^a-zA-Z0-9!@#$%^&*()_+=\-[\]{}|\\;:&#39;",.<>/?]/g 但是这样写比较复杂,而且容易遗漏。另一种思路是:我们允许所有键盘上可输入的可见字符(非空白字符),但是要注意空格通常允许在密码中?根据需求,密码一般允许空格,所以我们也允许空格。 实际上,我们也可以使用:/[^\x21-\x7E]/g 来匹配所有非ASCII可见字符(从!到~,包括字母数字所有特殊字符)。但是注意,这个范围包括了大小写字母数字特殊字符,并且排除了空格空格的ASCII是32,但我们的范围从33开始,所以空格在内)。但是这样也会包含一些我们想要的字符吗?实际上,从!到~,就是键盘上常见的字符(除了空格)。所以这个正则表达式可以匹配所有非可见ASCII字符(即匹配到我们允许字符,然后替换掉)。 但是,用户的需求是只能输入大小写字母数字特殊字符,所以我们也可以直接使用这个范围:[^!-~] 但是注意,在正则表达式中,我们可以用[\x21-\x7E]表示可见字符,那么非这些字符就是[^\x21-\x7E]。但是注意,这个范围包括了空格(ASCII 32)吗?我们看一下:\x21是33,\x7E是126,所以空格32)在内,因此这个正则表达式会影响空格,因为空格被匹配到了?对,空格32)在[^\x21-\x7E]里面,因为[^\x21-\x7E]表示除了33到126以外的字符空格32)属于这个“以外”,所以会被匹配到并替换掉。因此,这样写会同时禁止空格,符合要求。 但是,为了更明确,我们也可以写成:/[^\w!@#$%^&*()_+=\-[\]{}|\\;:&#39;",.<>/?]/g,但是这样写容易遗漏特殊字符。 考虑到简单性全面性,我们使用[^\x21-\x7E]来匹配所有非可见ASCII字符(包括空格、制表符等),然后替换为空。 但是,注意:这个范围包括了所有可见ASCII字符,也就是允许了大小写字母数字特殊字符,所以符合要求。 因此,我们可以这样写: <el-input oninput="value=value.replace(/[^\x21-\x7E]/g, &#39;&#39;)" /> 但是,用户要求的是密码输入框,通常我们会使用type="password",所以我们可以这样写: 示例代码: <el-input type="password" v-model="password" oninput="value=value.replace(/[^\x21-\x7E]/g, &#39;&#39;)" /> 但是,在Vue中,我们通常推荐使用oninput这样的内联事件,而是使用方法来处理。另外,在Element UI中,也可以使用自定义指令或者使用@input事件。 方法一:使用@input事件(在模板中) <el-input type="password" v-model="password" @input="handleInput"></el-input> 然后在methods中定义handleInput方法: methods: { handleInput(value) { this.password = value.replace(/[^\x21-\x7E]/g, &#39;&#39;); } } 但是这样写可能会导致光标位置问题(因为直接替换了值,光标会跳到末尾)。所以我们可以使用计算属性或者watch,但是这样可能够实时。 方法二:使用自定义指令(全局指令或局部指令) 参考引用[2]中的全局指令方法,我们可以创建一个指令来限制输入。 我们可以定义一个指令,例如v-input-pattern,然后在指令中处理输入事件。 但是,为了简单,我们也可以使用一个自定义指令来限制输入内容。 指令示例(全局指令): Vue.directive(&#39;input-pattern&#39;, { inserted: function (el) { el.addEventListener(&#39;input&#39;, function (e) { e.target.value = e.target.value.replace(/[^\x21-\x7E]/g, &#39;&#39;); // 触发input事件以更新v-model e.target.dispatchEvent(new Event(&#39;input&#39;)); }) } }); 然后在el-input上使用: <el-input type="password" v-model="password" v-input-pattern></el-input> 但是,这种方法也会导致光标位置问题。为了解决光标位置问题,我们可以在替换之前记录光标位置,替换后恢复光标位置。 改进指令: Vue.directive(&#39;input-pattern&#39;, { inserted: function (el) { el.addEventListener(&#39;input&#39;, function (e) { const start = e.target.selectionStart; const end = e.target.selectionEnd; e.target.value = e.target.value.replace(/[^\x21-\x7E]/g, &#39;&#39;); // 恢复光标位置 e.target.setSelectionRange(start, end); e.target.dispatchEvent(new Event(&#39;input&#39;)); }); } }); 但是,由于我们替换了字符串,光标位置可能需要调整。实际上,如果删除了中间某些字符,光标位置会前移,所以上述直接设置原来的startend可能准确(因为字符串变短了)。所以更精确的做法是计算替换后光标应该所在的位置,但这样比较复杂。 另外,引用[4]中使用了formatterparser,但这是element-ui中用于格式化显示的,也可以尝试。 方法三:使用formatterparser(针对element-ui) 在element-ui中,el-input组件提供了formatterparser,可以用于格式化输入值。但是注意,formatterparser通常用于格式化显示(比如金额输入),但也可以用来限制输入。 我们可以这样写: <el-input type="password" v-model="password" :formatter="formatPassword" :parser="formatPassword"></el-input> 然后在methods中定义formatPassword方法: formatPassword(value) { return value.replace(/[^\x21-\x7E]/g, &#39;&#39;); } 但是,注意:formatterparser在element-ui中主要用于输入框的显示格式化,在输入过程中,它会在失去焦点时格式化,获得焦点时又变回原值。所以这种方式是实时的,可能符合我们的实时限制需求。 因此,我们推荐使用@input事件,并解决光标问题。 改进的@input事件处理方法(使用Vue的v-model@input结合): <el-input type="password" v-model="password" @input="handleInput"></el-input> 在handleInput中,我们使用一个中间变量来避免直接修改v-model导致的光标问题,而是通过$nextTick来设置值?但这样并直接。 另一种方法:使用debounce(防抖)可能并解决问题。 实际上,我们可以使用一个中间变量,然后通过input事件来更新,但这样会稍微复杂。 考虑到输入内容通常会太多,光标位置问题可能并严重,用户可能可以接受。如果要求严格,我们可以使用自定义指令并精确计算光标位置。 这里我们提供一个相对简单的解决光标位置问题的方法: 在handleInput中,我们记录当前光标位置,然后替换字符串,再设置光标位置。但是我们需要通过ref来访问el-input的DOM。 示例: <el-input type="password" v-model="password" ref="pwdInput" @input="handleInput"></el-input> 在handleInput方法中: handleInput(value) { // 先保存光标位置 const inputEl = this.$refs.pwdInput.$el.querySelector(&#39;input&#39;); const start = inputEl.selectionStart; const end = inputEl.selectionEnd; // 替换非允许字符 const newVal = value.replace(/[^\x21-\x7E]/g, &#39;&#39;); // 如果值改变了,才更新 if (newVal !== value) { this.password = newVal; // 在下一帧恢复光标位置 this.$nextTick(() => { // 因为替换后,字符串长度减少,光标位置可能超出新的字符串长度,所以取最小值 const newStart = Math.min(start, newVal.length); const newEnd = Math.min(end, newVal.length); inputEl.setSelectionRange(newStart, newEnd); }); } } 但是,这种方法在每次输入时都会触发,如果输入内容没有非法字符,则会更新,所以会影响光标位置;如果有非法字符,则更新后光标位置会被调整。 考虑到实现复杂度需求,我们也可以采用引用[1]中的方法,直接使用内联事件处理,这样简单且实时,但可能符合Vue的风格。 因此,根据具体情况选择。 总结:我们有多种方法,这里提供两种推荐方法: 方法1(简单,内联事件): <el-input type="password" v-model="password" oninput="value=value.replace(/[^\x21-\x7E]/g, &#39;&#39;)"></el-input> 方法2(使用Vue方法,解决光标问题): 模板: <el-input type="password" v-model="password" ref="pwdInput" @input="handlePasswordInput"></el-input> 方法: handlePasswordInput(value) { const inputEl = this.$refs.pwdInput.$el.querySelector(&#39;input&#39;); const start = inputEl.selectionStart; const end = inputEl.selectionEnd; const newVal = value.replace(/[^\x21-\x7E]/g, &#39;&#39;); if (newVal !== value) { this.password = newVal; this.$nextTick(() => { // 计算新的光标位置 // 因为删除了非法字符,所以光标位置可能变化,我们根据删除的位置调整 // 但是直接使用原来的位置可能准确,因为我们知道删除了几个字符。所以这里我们简单处理:将光标设置在当前位置减去被删除的字符数(但是很难计算) // 因此,我们采用保存原始位置,然后设置到新位置,但新位置不能超过新字符串长度 inputEl.setSelectionRange(Math.min(start, newVal.length), Math.min(end, newVal.length)); }); } } 注意:方法2在非法字符出现在光标之前时,光标位置会前移(因为删除了字符,后面的字符前移,所以光标位置也要前移相应的数量)。但是我们的代码中只是将光标设置到新字符串的相同索引位置(如果该索引还在新字符串长度内),这样如果非法字符出现在光标前面,那么光标位置相对于原始位置其实是向后移动了(因为光标前面的字符被删除了,所以光标位置索引变,但实际位置前移了)。这可能会导致光标位置准确。因此,更精确的方法需要计算从开始到光标位置有多少个非法字符,然后减去。但这样比较复杂。 考虑到复杂度,如果对光标位置要求高,可以使用内联事件(方法1)或者使用自定义指令(类似内联事件)。 另外,我们也可以使用第三方库或者更复杂的处理,但这里展开。 因此,如果项目对光标位置要求严格,推荐使用内联事件(方法1)。如果要求严格,可以考虑更复杂的光标位置计算。 最后,我们也可以使用已有的第三方指令,比如v-input-filter(如果有的话)。 综上所述,我们给出两种方案,用户可以根据需要选择。 注意:我们使用的正则表达式是/[^\x21-\x7E]/g,它允许所有ASCII可见字符(从33到126),包括大小写字母数字特殊字符,并且排除了空格(因为空格的ASCII是32,在这个范围,所以会被替换掉)。同时也排除了其他可见字符(如控制字符等)。所以满足要求。 如果用户需要允许空格,那么可以调整正则表达式,但需求中并没有要求允许空格,所以我们默认允许。 如果用户需要允许空格,那么我们可以将正则表达式改为:/[^\x20-\x7E]/g,这样空格32)也被包含在内。 但是需求中只要求大小写字母数字特殊字符,通常特殊字符包括空格(因为空格在密码中可能被接受),所以我们使用[^\x21-\x7E]。 </think>要控制 `el-input` 密码输入框只允许输入大小写字母数字特殊字符,可以通过以下方法实现(基于 Element UI): ### 方法一:使用正则表达式过滤(推荐) ```html <template> <el-input type="password" v-model="password" @input="handleInput" placeholder="请输入密码(大小写字母/数字/特殊字符)" ></el-input> </template> <script> export default { data() { return { password: &#39;&#39; }; }, methods: { handleInput(value) { // 正则说明:只保留大小写字母数字常见特殊字符 this.password = value.replace(/[^a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};:&#39;",.<>/?\\|`~]/g, &#39;&#39;); } } }; </script> ``` ### 方法二:使用自定义指令(全局复用) 1. 创建全局指令 `v-password-char`: ```javascript // main.js Vue.directive(&#39;password-char&#39;, { inserted(el) { const input = el.querySelector(&#39;input&#39;); input.addEventListener(&#39;input&#39;, (e) => { e.target.value = e.target.value.replace( /[^a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};:&#39;",.<>/?\\|`~]/g, &#39;&#39; ); }); } }); ``` 2. 在组件中使用: ```html <el-input type="password" v-model="password" v-password-char ></el-input> ``` ### 方法三:内联正则过滤(简单场景) ```html <el-input type="password" v-model="password" oninput="value=value.replace(/[^a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};:&#39;",.<>/?\\|`~]/g,&#39;&#39;)" > </el-input> ``` ### 关键说明 1. **正则表达式解析**: - `/[^...]/g`:匹配**包含**在括号内的字符 - 允许字符范围: - 字母:`a-zA-Z` - 数字:`0-9` - 特殊字符:``!@#$%^&*()_+-=[]{};:&#39;",.<>/?\\|`~`` - 排除空格、中文、表情符号等非常规字符 2. **特殊字符转义**: - 正则中需转义的字符:`[ ] \ ^ -` 等需用`\`转义 - 例如 `\[` 表示字面量 `[` 3. **注意事项**: - 使用 `@input` 事件而非 `@change` 实现实时过滤 - 密码框需设置 `type="password"` 隐藏输入内容 - 特殊字符范围可根据需求调整(如移除`` `|``等) ### 效果验证 输入以下内容时: ``` Hello123!@# 你好 😊 空格 ``` 实际存储值: ``` Hello123!@# ``` 中文字符空格、表情符号会被自动过滤[^1][^4]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值