安装依赖
npm install simple-keyboard --save
npm install simple-keyboard-layouts --save //中文字库
在components里面创建
主文件也就是index.vue(直接复制就可以)
<template>
<div :class="keyboardClass"></div>
</template>
<script>
import Keyboard from 'simple-keyboard'
import 'simple-keyboard/build/css/index.css'
import layout from 'simple-keyboard-layouts/build/layouts/chinese' // 中文字库
export default {
name: 'SimpleKeyboard',
props: {
keyboardClass: {
default: 'simple-keyboard',
type: String,
},
maxLength: { default: '' },
},
data: () => ({
keyboard: null,
displayDefault: {
'{bksp}': 'backspace',
'{lock}': '切换',
// '{enter}': '←┘enter',
'{enter}': '< enter',
'{tab}': 'tab',
'{shift}': 'shift',
'{change}': '中文',
'{space}': ' ',
'{clear}': '清空',
'{close}': '关闭'
}
}),
mounted () {
this.keyboard = new Keyboard(this.keyboardClass, {
onChange: this.onChange,
onKeyPress: this.onKeyPress,
layoutCandidates: layout.layoutCandidates,
layout: {
// 默认布局
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 , . / {clear}',
'{change} {space} {close}',
],
// shift布局
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 < > ? {clear}',
'{change} {space} {close}',
],
},
// 按钮展示文字
display: this.displayDefault,
// 按钮样式
buttonTheme: [
{
class: 'hg-red close',
buttons: '{close}',
},
{
class: 'change',
buttons: '{change}',
},
],
// 输入限制长度
maxLength: this.maxLength,
})
},
methods: {
onChange (input) {
this.$emit('onChange', input) // 输入值向外传递
},
// 重写清空按钮
onChangeKey () {
this.keyboard.setInput('')
this.$emit('empty')
},
// @focus 触发时赋值 封装组件调用
onChangeFocus (value) {
this.keyboard.setInput(value)
},
// 点击键盘
onKeyPress (button, $event) {
// 点击关闭
if (button === '{close}') {
// 子组件调用父组件的关闭按钮方法
this.$parent.closekeyboard()
return false
}
else if (button === '{change}') {
// 切换中英文输入法
if (this.keyboard.options.layoutCandidates !== null) {
this.$set(this.displayDefault, '{change}', '英文')
// 切换至英文
this.keyboard.setOptions({
layoutCandidates: null,
display: this.displayDefault,
})
} else {
// 切换至中文
this.$set(this.displayDefault, '{change}', '中文')
this.keyboard.setOptions({
layoutCandidates: layout.layoutCandidates,
display: this.displayDefault,
})
}
}
else if (button === '{clear}') {
this.onChangeKey()
}
else {
let value =
$event.target.offsetParent.parentElement.children[0].children[0].value
// 输入框有默认值时,覆写
if (value) {
this.keyboard.setInput(value)
}
this.$emit('onKeyPress', button)
}
if (button === '{shift}' || button === '{lock}') this.handleShift()
},
// 切换shift/默认布局
handleShift () {
let currentLayout = this.keyboard.options.layoutName
let shiftToggle = currentLayout === 'default' ? 'shift' : 'default'
this.keyboard.setOptions({
layoutName: shiftToggle,
})
},
},
}
</script>
<style lang="scss">
//这块样式可以根据自己的需求调整
// @deep: ~">>>";
// 这块样式可以根据自己的需求调整
// .hg-candidate-box {
// position: fixed;
// width: 100%;
// font-size: 42px;
// background: rgba(256, 256, 256);
// z-index: 9999;
// .hg-candidate-box-list {
// .hg-candidate-box-list-item {
// padding: 0 20px;
// }
// }
// }
.hg-rows {
// width: 100% !important;
.hg-row {
align-items: center;
// height: 50px;
// .hg-button {
// height: 50px;
// font-size: 24px;
// }
}
}
// .hg-theme-default {
// width: 1080px;
// height: 330px;
// left: 0;
// position: fixed;
// bottom: 10px;
// .hg-button {
// &.hg-red {
// background: #db3e5d;
// color: white;
// &.close {
// max-width: 200px;
// }
// }
// &.change {
// max-width: 200px;
// }
// }
// }
.simple-keyboard {
position: fixed;
width: 100%;
// font-size: 42px;
left: 18%;
bottom: 0;
// transform: translateX(-50%);
background: rgba(256, 256, 256);
z-index: 9999;
max-width: 1000px;
// padding: 15px;
// margin: 0 auto;
// margin-top: 380px;
box-shadow: 0 4px 0 #b2b2b2, 0 7px 16px rgba(0, 0, 0, 0.6);
.hg-candidate-box {
left: 0;
top: 0;
position: relative;
font-size: 30px;
margin-top: 0;
transform: translateY(0);
max-width: 100%;
}
}
.hg-theme-default .hg-button {
height: 50px;
margin: 8px 10px;
font-size: 23px;
background-color: #fff;
border-radius: 8px;
cursor: pointer;
-webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0, 0, 0, 0.7);
box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0, 0, 0, 0.7);
}
.hg-theme-default .hg-button.hg-standardBtn:active {
box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0, 0, 0, 0.9);
background-color: #efefef;
}
.simple-keyboard.hg-layout-default .hg-button.bksp {
height: 50px;
margin: 8px 10px;
font-size: 23px;
background-color: #fff;
border-radius: 8px;
cursor: pointer;
-webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0, 0, 0, 0.7);
box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0, 0, 0, 0.7);
background: #a8001e;
color: white;
}
.simple-keyboard.hg-layout-default .hg-button.bksp:active {
box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0, 0, 0, 0.9);
background-color: #efefef;
color: #000000;
}
.simple-keyboard.hg-layout-default .hg-button.enter {
height: 50px;
margin: 8px 10px;
font-size: 23px;
background-color: #fff;
border-radius: 8px;
cursor: pointer;
-webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0, 0, 0, 0.7);
box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0, 0, 0, 0.7);
background: #a8001e;
color: white;
}
.simple-keyboard.hg-layout-default .hg-button.enter:active {
box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0, 0, 0, 0.9);
background-color: #efefef;
color: #000000;
}
</style>
再封装成一个便捷组件
<template>
<div>
<div v-show="showKeyboard">
<SimpleKeyboard
ref="refSimpleKeyboard"
class="Keyboard"
@onChange="onChangeKeyboard"
@empty="empty"
/>
</div>
</div>
</template>
<script>
import SimpleKeyboard from './index'
export default {
name: 'Keyboard',
components: {
SimpleKeyboard
},
data () {
return {
showKeyboard: false, // 键盘默认隐藏
value: '',
key: ''
}
},
watch: {
key (val) {
this.key = val
if (this.showKeyboard) {
this.showKeyboard = false
setTimeout(() => {
this.showKeyboard = true
}, 100)
}
},
},
methods: {
// inpuit获取焦点显示虚拟键盘
onInputFocus (res) {
this.showKeyboard = true
},
// 给输入框赋值
onChangeKeyboard (input) {
this.$emit('input', { value: input, key: this.key });
},
// 隐藏键盘 父组件调用
closeInputFocus () {
this.showKeyboard = false
},
// 隐藏键盘 子组件调用
closekeyboard () {
this.showKeyboard = false
},
// 清空输入框
empty () {
this.$emit('input', { value: '', key: this.key });
},
// 给虚拟键盘赋当前输入框的值
setKeyboardInput (input) {
this.$refs.refSimpleKeyboard.onChangeFocus(input)
}
}
}
</script>
<style lang="scss" scoped>
// 键盘样式
.Keyboard {
position: absolute;
}
</style>
在main.js里面全局引入就不用每次都引入了
import Keyboard from '@/components/SimpleKeyboard/Keyboard.vue'
Vue.component("Keyboard", Keyboard);
使用的话就是直接是
@focus="focusEvent('labelCode', labelCode)"
第一个值是软键盘点击事件绑定输入框的key 第二个是将输入框原有的值传进去给组件
返回的是一个对象{value:'',key:''}
<el-input
ref="barCodeInput"
prefix-icon="el-icon-search"
placeholder="请扫码或者输入条码"
v-model="labelCode"
@keyup.enter.native="addEvent"
@focus="focusEvent('labelCode', labelCode)"
clearable
>
</el-input>
<!-- 软键盘 -->
<Keyboard ref="Keyboard" @input="updateInputValue"></Keyboard>
主要是两个事件
第一个输入框获取焦点事件打开软键盘
// 软键盘抬起事件
focusEvent (event, value) {
// 当前input获取焦点时,显示键盘
this.$refs.Keyboard.showKeyboard = true
// 传入绑定值(字符串)
this.$refs.Keyboard.key = event
//传入当前值
this.$refs.Keyboard.setKeyboardInput(value)
},
第二个是软键盘的点击键盘事件将值返回给输入框
// 软键盘事件
updateInputValue (value) {
console.log(value)
//根据key 回写input值
let parameter = value.key.split(".")
console.log(parameter);
if (parameter.length == 1) {
this[value.key] = value.value
} else if (parameter.length == 2) {
let par0 = parameter[0]
let par1 = parameter[1]
this.$set(this[par0], par1, value.value)
} else if (parameter.length == 3) {
let par0 = parameter[0]
let par1 = parameter[1]
let par2 = parameter[2]
this.$set(this[par0][par1], par2, value.value)
}
this.$forceUpdate()
}