在网上搜了很多的解决方案,基本上都没有完美解决的,而完美解决就是在浏览器设置中禁止记住密码(ps:小菜鸟的内心想法),项目的需求非得实现页面不记住密码的功能,只能硬着头皮实现了。
- autocomplete="off" 现代浏览器已经不支持,所以直接放弃了对密码框设置,直接使用 autocomplete="new-password" ,亲测Chrome(v88.0.4324.104)、edge(v88.0.705.56)及火狐(v67)可用,但火狐(v85)还是会提示记住密码。参考:关闭表单自动填充
- 使用 type="text",手动替换文本框内容小圆点 “●”。(没有用星号 “”做替换是因为用户输入“”的话,没办法处理 )
最终选择用type='text',并手动替换内容。
先看效果:
基本上实现了el-input密码框的功能。
template
<template>
<el-input
v-model="showValue"
type="text"
v-bind="$attrs"
@input.native="handleChangePSW($event)"
/>
</template>
script
<script>
export default {
name: 'Password',
props: {
value: {
type: String,
default: ''
},
type: {
type: String,
default: 'password'
}
},
data() {
return {
password: '', // 真实密码
showValue: '', // 显示字符
replaceChar: '•' // ●ꔷ•᛫・
}
},
computed: {
},
watch: {
type(value) {
if (value === 'password') {
this.showValue = this.replaceChar.repeat(this.value.length)
} else {
this.showValue = this.value
}
}
},
methods: {
handleChangePSW(e) {
console.log(e, 'e')
const value = e.target.value // 当前的值
if (!value) {
this.password = ''
this.showValue = ''
} else {
// 只能输入大小写字母、数字、字符
const reg = /^[\w|~`!@#$%^&*()_-+=<>?:"{}\;',./:"<>?[]|·~!¥……()——【】、;‘’,。、:“”《》?•]+$/g
if (!reg.test(value)) {
// e.target.value = value.replace(/[\u4e00-\u9fa5]/gm, '')
e.target.value = this.showValue // 将之前未包含中文的值,重新赋值
return
}
if (this.type === 'password') {
const oldVal = this.password // 之前的值
let passwordShow = '' // 当前输入下需要显示的值,及n个*的字符串
let text = '' // 当前input事件输入的值,如果是删除就没有值
// 当前input指针的位置,不一定是在最后
const startPoint = e.target.selectionStart
const endPoint = e.target.selectionEnd
let leftNum = 0 // 输入后左边保留多少
let rightNum = 0 // 输入后右边保留多少
let isLeft = true
for (let i = 0; i < value.length; i++) {
passwordShow += this.replaceChar
if (value[i] === this.replaceChar) { // ●ꔷ•᛫・
if (isLeft) {
leftNum++
} else {
rightNum++
}
continue
}
text += value[i]
isLeft = false
}
if (text) {
this.password = oldVal.slice(0, leftNum) + text + oldVal.slice(oldVal.length - rightNum)
} else {
if (startPoint >= value.length) {
this.password = oldVal.slice(0, startPoint) + oldVal.slice(oldVal.length - leftNum - rightNum + startPoint)
} else {
this.password = oldVal.slice(0, startPoint) + oldVal.slice(oldVal.length - leftNum - rightNum + endPoint)
}
}
this.showValue = passwordShow
this.$nextTick(() => {
e.target.setSelectionRange(startPoint, startPoint)
})
} else {
this.password = this.showValue = value
}
}
this.$emit('input', this.password)
}
}
}
</script>
上面的代码是封装成一个组件的代码,只需要在父组件中引用,就可以实现模拟密码框的功能,基本上实现了替换功能、限制中文的输入、密码的查看;下图就是在父组件的引用代码。
图中红色框就是el-input的type='password'的功能代码,绿色框中的代码就是模仿实现。