vue 封装密码输入框(屏蔽浏览器反显,禁止粘贴)
备注:使用了ant-design-vue,可以换其他组件输入框或原生
<template>
<a-input
style="ime-mode: disabled"
:value="hideValue"
@change="valueChange"
@compositionstart="compositionstartHandle"
@compositionend="compositionendHandle"
@paste.capture.prevent="pasteHandle"
ref="password-input"
:placeholder="placeholder"
>
<a-icon @click="isHidden = !isHidden" v-if="isHidden" slot="suffix" type="eye-invisible" style="color: rgba(0,0,0,.45)" />
<a-icon @click="isHidden = !isHidden" v-else slot="suffix" type="eye" style="color: rgba(0,0,0,.45)" />
</a-input>
</template>
<script>
export default {
name: 'InputPassword',
props: {
value: {
type: String,
},
placeholder: {
type: String,
default: '请输入',
},
},
// model: {
// prop: 'value', //指向props的参数名
// event: 'input' //事件名称
// },
data() {
return {
hideValue: '',
isHidden: true,
compositionStatue: false,
compositionStartCursorIndex: 0
}
},
watch: {
isHidden: {
handler() {
this.render(this.value)
},
},
value: {
handler(val) {
this.render(val)
},
},
},
methods: {
// 对输入框的显示hideValue进行渲染 val 是实际的value
render(val) {
if (!this.isHidden) {
this.hideValue = val
} else {
this.hideValue = val.replace(/[^•]/g, '•')
}
},
// 事件
valueChange(event) {
// console.log(event, 'zs------------jfsevent')
// console.log(this.$refs['password-input'])
// console.log(this.$refs['password-input'].selectionStart, 'zsselectionStart')
if (this.compositionStatue) {
// 进行中文输入时不执行 inputHandle 函数
return false
}
let el = event.target
// console.log(this.value, el, 'zs------------valueChange')
// console.log(el.selectionStart, 'zs----elselectionStart')
let oldPwd = this.value || ''
let newPwd = ''
let cursorIndex = el.selectionStart
let val = el.value
// console.log(el, val, cursorIndex,'zs--------val')
if (this.isHidden) {
// 删除字符
if (oldPwd && oldPwd.length > val.length) {
let delEndIndex = oldPwd.length - val.length + cursorIndex
newPwd = oldPwd.substring(0, cursorIndex) + oldPwd.substring(delEndIndex)
} else {
let reg = /[^•]/.exec(val) // 获取虚假密码中新增的密码字符
if (reg) {
// 如果存在新增密码字符,则进行输入输入处理
newPwd = this.insertStr(oldPwd, reg.index, reg[0]) // 将用户新输入的字符插入旧的真实密码
this.cursorMove(el, reg.index + 1) // 设置光标的位置
} else {
// this.render() 二次触发
// 如果不存在新增密码字符,不做改变
newPwd = oldPwd
}
}
} else {
newPwd = el.value
}
this.$emit('input', newPwd)
},
/**
* 根据位置在字符串中插入字符串
* @params soure 原字符串
* @params start 位置
* @params newStr 要插入的字符串
*/
insertStr(soure, start, newStr) {
return soure.slice(0, start) + newStr + soure.slice(start)
},
/**
* 控制光标的位置
*/
cursorMove(elem, spos) {
// spos 光标的位置 -1为最后一位
if (spos < 0) spos = elem.value.length
if (elem.setSelectionRange) {
//兼容火狐,谷歌
setTimeout(function () {
elem.setSelectionRange(spos, spos)
elem.focus()
}, 0)
} else if (elem.createTextRange) {
//兼容IE
var rng = elem.createTextRange()
rng.move('character', spos)
rng.select()
}
},
compositionstartHandle(event) {
// console.log(event,event.target)
// this.compositionStartCursorIndex = this.$refs['password-input'].selectionStart // 记录进行中文输入时光标的位置
this.compositionStartCursorIndex = event.target.selectionStart // 记录进行中文输入时光标的位置
this.compositionStatue = true
},
compositionendHandle(event) {
this.limitCN(event.target)
this.compositionStatue = false
this.compositionLength = 0
},
pasteHandle() {
return false
},
// 限制中文输入
limitCN(el) {
// let val = this.$refs['password-input'].value; // 获取输入框中的值
let val = el.value; // 获取输入框中的值
// eslint-disable-next-line no-control-regex
val = val.replace(/[^\x00-\x80•]/gi, '');
el.value = val;
this.cursorMove(
el,
this.compositionStartCursorIndex
); // 将光标重置为中文输入前的位置
}
},
}
</script>
<style lang='less' scoped>
</style>
ps: 参考了其他博客文档,忘记了链接。。。