参考:
完美解决 element-ui input=password 在浏览器会自动填充密码的问题
背景:
领导要求去掉登录页的账号密码表单的自动显示账号密码候选框
定位:
- chrome 版本 126.0.6478.127 , 现有表单用的是原生 input 元素, 之前已经加了
autocomplete="off"
和readonly + onfocus 时去掉 readonly
, 看起来之前就尝试去掉候选框了, 但是没啥效果; 账号和密码输入框都会触发, 要不就是一开始不触发, 清空后重新输入 或 多次 tab 切换/点击重新获取焦点后又触发了 - 先看 autocomplete 属性, 结果发现 off 和 new-password 都不管用
- 之前记得看到过使用额外的隐藏 input 欺骗浏览器的方案, 但是不想改现有表单结构 + 多写代码, 先 pass ;
- 再试 readonly , 毕竟之前加的这个, 有时还是生效的, 于是搜到了上面的参考文章, 参考它成功解决问题 --- 坑爹的是, 尝试过程中经常是本地 localhost 没问题, 发到测试环境域名后效果不好...
代码:
js
<!-- vue 写的 -->
<!-- 原代码 -->
<!-- 遍历配置表单输入框配置对象数组 inputConfig , 显示账号和密码输入框 -->
<input v-model="form[item.attrName]"
ref="loginFormInput"
:type="item.type"
:name="item.name"
:id="item.id"
:placeholder="item.placeholder"
:autocomplete="item.type === 'password' ? 'on' : 'off'"
:readonly="item.type !== 'password'"
onfocus="this.removeAttribute('readonly');"
@blur="blur(item,form[item.val],index)"
@focus="focus(index)"
@change="change(form[item.val], item.val)"/>
<!-- 新代码 -->
<input v-model="form[item.val]"
ref="loginFormInput"
:type="item.type"
:name="item.name"
:id="item.id"
:placeholder="item.placeholder"
autocomplete="off" // 变动
:readonly="true" // 变动
// 删除 onfocus
@blur="blur(item,form[item.val],index)" // 内部变动
@focus="focus(index)" // 内部变动
@mousedown="handleMouseDown(index)" // 新增
@change="change(form[item.val], item.val)"/>
<script>
export default {
methods: {
// 动态设置 input 的 readonly , 避免浏览器显示候选框
handleMouseDown(index) {
const $inputEl = this.$refs.loginFormInput[index];
if (this.form[this.inputConfig[index].attrName] === '') {
$inputEl.setAttribute('readonly', 'readonly');
setTimeout(() => {
$inputEl.removeAttribute('readonly');
});
} else {
$inputEl.removeAttribute('readonly');
}
},
focus(index) {
// 新增的相关代码
// 避免使用 tab 键选中输入框时浏览器显示候选框
this.handleMouseDown(index);
},
blur(item, val, index) {
// 新增的相关代码
// 失焦时设置 readonly , 不管输入框是否有值, 避免多次 tab 切换输入框后浏览器候选框又显示出来了
const $inputEl = this.$refs.loginFormInput[index];
$inputEl.setAttribute('readonly', 'readonly');
}
},
watch: {
'form.password': {
handler: function(val) {
// 新增的相关代码
// 此处使用 watch 值的变化,因为使用 @input 监听时用拼音输入有问题(可用 compositionstart 解决, 但麻烦)
if (!val) {
this.handleMouseDown(1);
}
},
deep: true
},
'form.userName': {
handler: function(val) {
// 新增的相关代码
// 此处使用 watch 值的变化,因为使用 @input 监听时用拼音输入有问题(可用 compositionstart 解决, 但麻烦)
if (!val) {
this.handleMouseDown(0);
}
},
deep: true
}
}
}
</script>
后记:
额... 领导说不用改了, 我理解错了, 说的不是去掉候选框, 是去掉候选框里某一条记录, 客户自己进密码管理器删了就行...