1.管理后台项目 每个页面都有模糊搜索,之前是使用外接键盘或者扫码枪进行输入,完全没有问题,但是最近客户使用的是触屏手动输入,就发现了问题,输入框上的值并不会被监听到,也不会触发el-input框自带的enter,以及change事件,这时候就想着接入一个 虚拟键盘,在触屏项目中使用,接入完成后本以为可以成功,但是发现,通过js给el-input value赋值,v-model绑定值不会同步
问题:.赋值后,界面显示字段已更改,获取v-model的参数,发现不会同步更改
解决办法:
v-model只是一种语法糖,底层的方法还是去监听input事件。所以可以使用dispatchEvent事件给元素分配一个input事件,这样可以手动触发 inputElement 的 input 事件,同时可以触发 v-model 机制。IE 好像不支持(但可以 polyfill)。
el.value(newval)
el.dispatchEvent(new Event(\'input\'));
el为input元素
解决!
PS:
如果v-model有lazy修饰符的时候,触发得是change事件
el.dispatchEvent(new Event(‘change’));
完整步骤:
1.先安装
npm i simple-keyboard -S
2.我这里是单独写了一个keyboard.vue的组件
<template>
<div :class="keyboardClass"></div>
</template>
<script>
import Keyboard from "simple-keyboard";
import "simple-keyboard/build/css/index.css";
export default {
name: "SimpleKeyboard",
props: {
keyboardClass: {
default: "simple-keyboard",
type: String,
},
input: {
type: String,
},
layout: {
type: Object,
default: function () {
return {
default: [
"` 1 2 3 4 5 6 7 8 9 0 - = {bksp}",
"{tab} q w e r t y u i o p [ ] \\",
"{lock} a s d f g h j k l ; ' {enter}",
"{shift} z x c v b n m , . / {shift}",
"@ {space}",
],
shift: [
"~ ! @ # $ % ^ & * ( ) _ + {bksp}",
"{tab} Q W E R T Y U I O P { } |",
'{lock} A S D F G H J K L : " {enter}',
"{shift} Z X C V B N M < > ? {shift}",
"@ {space}",
],
};
},
},
},
data: () => ({
keyboard: null,
}),
mounted() {
this.keyboard = new Keyboard(this.keyboardClass, {
onChange: this.onChange,
onKeyPress: this.onKeyPress,
});
this.keyboard.setOptions({
layoutName: "default",
layout: this.layout,
display: {
"{enter}": "close",
"{shift}": "shift",
"{bksp}": "del",
"{tab}": "tab",
"{space}": "space",
"{lock}": "caps",
},
});
},
methods: {
onChange(input) {
this.$emit("onChange", input);
},
onKeyPress(button) {
this.$emit("onKeyPress", button);
/**
* If you want to handle the shift and caps lock buttons
*/
if (button === "{shift}" || button === "{lock}") this.handleShift();
},
handleShift() {
let currentLayout = this.keyboard.options.layoutName;
let shiftToggle = currentLayout === "default" ? "shift" : "default";
this.keyboard.setOptions({
layoutName: shiftToggle,
});
},
},
watch: {
input(input) {
this.keyboard.setInput(input);
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
tips: 因为我这边有几个键需要自定义,所以在mounted中进行了修改~
3. 在需要应用的页面 引入 注册 使用即可 我这里是在keyIndex.vue页面中引入啦~
<template>
<div>
<svg-icon icon-class="keyboard" @click="click" />
<SimpleKeyboard
v-if="isShow"
@onChange="onChange"
@onKeyPress="onKeyPress"
:input="input"
/>
</div>
</template>
<script>
import SimpleKeyboard from "@/components/keyboard/keyboard";
export default {
name: "keyboard",
components: { SimpleKeyboard },
data() {
return {
input: "",
currentInputDom: "",
isShow: false,
};
},
beforeUpdate() {
this.$nextTick(() => {
this.findInput();
});
},
methods: {
click() {
this.isShow = !this.isShow;
},
onChange(input) {
console.log(input, "input");
let that = this;
that.input = input;
that.currentInputDom.value = input + "";
that.currentInputDom.dispatchEvent(new Event("input"));
},
onKeyPress(button) {
let that = this;
if (button == "{enter}") {
that.isShow = false;
}
},
//给页面中input框添加点击事件
findInput() {
let that = this;
let list = document.getElementsByTagName("input");
for (let i = 0; i < list.length; i++) {
let inputDom = list[i];
if (inputDom.type == "text" || inputDom.type == "password") {
console.log(inputDom.readOnly, i);
if (!inputDom.readOnly) {
inputDom.addEventListener("click", function (event) {
that.input = event.target.value; //获取到输入框的值
that.currentInputDom = event.target;
});
// console.log(inputDom.type, i);
}
}
}
},
},
};
</script>
<style scoped>
.keyboard-svg {
display: inline-block;
cursor: pointer;
fill: #5a5e66;
width: 20px;
height: 20px;
vertical-align: 10px;
}
.hg-theme-default {
position: fixed;
z-index: 9999;
width: 75%;
left: 20%;
bottom: 30px;
}
</style>
tips:因为每个页面都有input框,所以我这边写了一个方法 findInput(),找到页面中所有的input框并添加点击事件,获取到输入的值。
1.首先:给页面中input框添加点击事件,也要区分因为日期选择器,下拉框噢。本质上也属于输入框,但它们不是真的哦~
所以:inputDom.type == “text” || inputDom.type == "password"时,添加点击事件
2.
inputDom.addEventListener("click", function (event) {
//js赋值
that.input = event.target.value;
that.currentInputDom = event.target;
});
3.onChange事件 是键盘按键 点击时触发
onChange(input) {
//input: 为点击的键盘值
console.log(input, "input");
let that = this;
that.input = input;// 赋值给键盘上绑定的值
that.currentInputDom.value = input + ""; //value 值格式为字符串,所以要+ ''
that.currentInputDom.dispatchEvent(new Event("input")); //更新v-model的值
},
实现效果 :点击旁边的搜索功能也是最新输入的值噢~ 更新成功