Vue自定义组件: 自动切换输入法的录入框,屏蔽输入法的录入框,屏蔽中文输入法
vue3.5版本
<template>
<div class="input-scan">
<input v-model="model" class="text" :style="style" />
<input v-model="model" class="pass" :style="style" id="input-scan-pass" ref="passRef" @keyup.enter="onKeyUpEnter"
type="password" :name="randomName" autocomplete="off" />
</div>
</template>
<script lang="ts" setup>
// 扫码输入框, 屏蔽中文输入法 autocomplete="new-password" autocomplete="off":防止浏览器保存密码
defineOptions({
name: 'InputScan'
})
const props = defineProps({
style: {
type: String,
default: () => '',
},
})
const emit = defineEmits(['onEnter']) // 监听回车事件
const model = defineModel({ default: ' ' }) // 放一个空格, 防止浏览器自动填充
const passRef = ref()
const randomName = ref('password_')
onMounted(() => {
// 随机生成name, 防止浏览器自动填充(不是所有浏览器都有效)
randomName.value = 'password_' + Math.random().toString(36).substring(2, 15)
})
const onKeyUpEnter = () => {
emit('onEnter', model.value.trim())
passRef.value.select()
}
</script>
<style scoped>
.input-scan {
position: relative;
height: 39px;
width: 290px;
margin: 10px;
}
.text,
.pass {
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
/* 等宽字体 */
font-family: 'Consolas', Courier, monospace;
font-size: large;
border-radius: 4px;
padding: 8px;
}
.text {
z-index: 1;
border: 1px solid lightgray;
}
.pass {
z-index: 2;
border: 0px solid red;
background-color: transparent;
caret-color: black;
color: transparent;
}
/* 选中后字体透明,蓝色背景50%透明 */
#input-scan-pass::selection {
color: transparent;
background-color: rgba(0, 0, 255, 0.5);
}
#input-scan-pass::-moz-selection {
color: transparent;
background-color: rgba(0, 0, 255, 0.5);
}
</style>
vue3版本
<template>
<div class="input-scan">
<input v-model="modelValue" class="text" :style="style" :class="class" />
<input v-model="modelValue" class="pass" @keyup.enter.native="keyupEnter" type="password" :style="style"
:class="class" />
</div>
</template>
<script lang="ts" setup>
//扫码输入框,通过把一个透明的密码框放在普通输入框的上面,实现强制转换输入法为英文输入法的效果
import { computed } from 'vue'
defineOptions({
name: 'InputScan'
})
const props = defineProps(['modelValue', 'style', 'class'])
const emit = defineEmits(['update:modelValue', 'keyup-enter'])
// 这里可以用const modelValue = useVModel(props, 'modelValue', emit)代替
const modelValue = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const keyupEnter = () => {
emit('keyup-enter', modelValue.value)
}
</script>
<style scoped>
.input-scan {
position: relative;
}
.text {
position: absolute;
}
.pass {
position: absolute;
z-index: 999999;
background-color: transparent;
color: transparent;
}
</style>
vue2版本
利用透明的密码输入框实现自动切换到英文输入法, 在密码输入框下面再放一个文本, 同步显示明文
<template>
<div id="HtmlInputScan">
<input :value="value" @input="input" type="text" class="text">
<input :value="value" @input="input" type="password" class="pass">
</div>
</template>
<script>
export default {
props: {
value: {
default: undefined
}
},
methods: {
// 实现双向绑定
input(e) {
this.$emit('input', e.target.value)
}
}
}
</script>
<style lang="scss" scoped>
#HtmlInputScan {
position: relative;
.text {
position: absolute;
top: 10px;
left: 10px;
width: 100%;
font-family: Consolas, Monaco, monospace;
}
.pass {
position: absolute;
top: 10px;
left: 10px;
z-index: 999999; //密码框放上面才能自动切换到英文
width: 100%;
font-family: Consolas, Monaco, monospace;
background-color: transparent;
color: transparent;
}
}
</style>
Vue2的双向绑定demo
HtmlInput.vue
<template>
<div>
<input :value="value" @input="input" type="text" >
</div>
</template>
<script>
export default {
props: {
// 接收父组件传入的v-model的值
value: {
default: ''
}
},
methods: {
// 推送值给父组件v-model绑定的变量, 实现双向绑定
input(e) {
this.$emit('input', e.target.value)
}
}
}
</script>
使用示例
<template>
<div>
<html-input v-model="inputValue" />
</div>
</template>
<script>
import HtmlInput from './HtmlInput.vue'
export default {
components: {
HtmlInput,
},
data() {
return {
inputValue: '123',
},
}
</script>