方法一 js实现
<template>
<!-- eslint-disable -->
<a-input :id="eid" v-bind="$attrs" :value="isShowPassword ? value : passwordHidden" @input="input" @clear="clear"
@copy="copy" @paste="paste" :allowClear="true">
<i class="mtico-login-password mtico-login" slot="prefix"></i>
<a-icon @click="isShowPassword = !isShowPassword" class="isShowPassword" slot="suffix" type="eye"
v-if="isShowPassword" />
<a-icon @click="isShowPassword = !isShowPassword" class="isShowPassword" slot="suffix" type="eye-invisible"
v-else />
</a-input>
</template>
<script>
export default {
name: "PasswordInput",
props: {
value: {
type: String,
default: ''
}
},
data () {
return {
eid: String(Math.random()),
isShowPassword: true,
selectionStart: 0,
selectionEnd: 0,
clipboardData: ''
}
},
computed: {
passwordHidden () {
return this.value.replace(/./g, '•')
}
},
methods: {
input (e) {
console.log('input', e)
let selectionStartCurrent = e.target.selectionStart
let selectionEndCurrent = e.target.selectionEnd
console.log('* input this.selectionStart', this.selectionStart)
console.log('* input this.selectionEnd', this.selectionEnd)
if (e.inputType === 'insertText') {
if (this.selectionStart === this.selectionEnd) {
this.$emit('input', this.value.substring(0, selectionStartCurrent - 1) + e.data + this.value.substring(selectionStartCurrent - 1))
} else {
this.$emit('input', this.value.substring(0, this.selectionStart) + e.data + this.value.substring(this.selectionEnd))
}
this.$nextTick(() => document.getElementById(this.eid).setSelectionRange(selectionStartCurrent, selectionEndCurrent))
} else if (e.inputType === 'deleteContentBackward') {
let newVal = e.target.value
let len = this.value.length - newVal.length
this.$emit('input', this.value.substring(0, selectionStartCurrent) + this.value.substring(selectionStartCurrent + len))
} else if (e.inputType === 'insertFromPaste') {
console.log('粘贴', this.clipboardData)
this.$emit('input', this.value.substring(0, this.selectionStart) + this.clipboardData + this.value.substring(this.selectionEnd))
} else if (['historyUndo', 'historyRedo'].includes(e.inputType)) {
console.log(e.inputType, e.target.value)
this.$emit('input', e.target.value)
}
},
clear (e) {
console.log('clear', e)
this.$emit('input', '')
},
copy (e) {
console.log('copy', e)
},
paste (e) {
console.log('paste', e)
this.clipboardData = e.clipboardData.getData('text')
},
selectionchange (e) {
let activeElement = e.target.activeElement
if (activeElement.id === this.eid) {
this.selectionStart = activeElement.selectionStart
this.selectionEnd = activeElement.selectionEnd
}
}
},
mounted () {
document.addEventListener('selectionchange', this.selectionchange)
},
}
</script>
<style lang="less" scoped>
.mtico-login {
font-size: 16px;
}
.isShowPassword {
cursor: pointer;
font-size: 16px;
}
</style>
方法二 CSS实现
/deep/.mask {
input {
-webkit-text-security: disc !important;
}
}
呵呵