268 lines
7.2 KiB
Vue
268 lines
7.2 KiB
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
|
|
},
|
|
input: {
|
|
default: ''
|
|
},
|
|
maxLength: { default: '' }
|
|
},
|
|
data: () => ({
|
|
copy: true,
|
|
keyboard: null,
|
|
displayDefault: {
|
|
'{bksp}': 'backspace',
|
|
'{lock}': 'Caps lock',
|
|
'{enter}': 'Enter',
|
|
'{tab}': 'Tab',
|
|
'{shift}': 'Shift',
|
|
'{change}': 'En<span class="font-s">/中文</span>',
|
|
'{space}': ' ',
|
|
'{clear}': 'Clear',
|
|
'{close}': 'Close'
|
|
},
|
|
buttonTheme: [
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{bksp}'
|
|
},
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{tab}'
|
|
},
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{enter}'
|
|
},
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{clear}'
|
|
},
|
|
{
|
|
class: 'hg-blue',
|
|
buttons: '{close}'
|
|
},
|
|
{
|
|
class: 'hg-blue',
|
|
buttons: '{change}'
|
|
},
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{lock}'
|
|
},
|
|
{
|
|
class: 'hg-gray',
|
|
buttons: '{shift}'
|
|
}
|
|
]
|
|
}),
|
|
mounted () {
|
|
this.keyboard = new Keyboard(this.keyboardClass, {
|
|
onChange: this.onChange,
|
|
onKeyPress: this.onKeyPress,
|
|
// layoutCandidates: layout.layoutCandidates,
|
|
layoutCandidates: null,
|
|
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: this.buttonTheme,
|
|
// 输入限制长度
|
|
maxLength: this.maxLength
|
|
})
|
|
},
|
|
methods: {
|
|
onChange (input) {
|
|
if (this.copy) {
|
|
this.$emit('onChange', this.input + input)
|
|
this.copy = !this.copy
|
|
return false
|
|
} else {
|
|
this.$emit('onChange', input)
|
|
}
|
|
},
|
|
onKeyPress (button, $event) {
|
|
// 点击关闭
|
|
if (button === '{close}' || button === '{enter}') {
|
|
// this.keyboard.destroy()
|
|
let arr = document.querySelectorAll('.hg-theme-default')
|
|
arr.forEach((ele) => {
|
|
ele.style.visibility = 'hidden'
|
|
})
|
|
return false
|
|
} else if (button === '{change}') {
|
|
// 切换中英文输入法
|
|
if (this.keyboard.options.layoutCandidates !== null) {
|
|
this.$set(this.displayDefault, '{change}', 'En<span class="font-s">/中文</span>')
|
|
// 切换至英文
|
|
this.keyboard.setOptions({
|
|
layoutCandidates: null,
|
|
display: this.displayDefault
|
|
})
|
|
} else {
|
|
// 切换至中文
|
|
this.$set(this.displayDefault, '{change}', '中文<span class="font-s">/En</span>')
|
|
this.keyboard.setOptions({
|
|
layoutCandidates: layout.layoutCandidates,
|
|
display: this.displayDefault
|
|
})
|
|
}
|
|
} else if (button === '{clear}') {
|
|
this.keyboard.clearInput()
|
|
} else if (button === '{shift}' || button === '{lock}') {
|
|
this.handleShift(button)
|
|
}
|
|
this.$emit('onKeyPress', button)
|
|
},
|
|
// 切换shift/默认布局
|
|
handleShift (button) {
|
|
let currentLayout = this.keyboard.options.layoutName
|
|
let shiftToggle = currentLayout === 'default' ? 'shift' : 'default'
|
|
this.keyboard.setOptions({
|
|
layoutName: shiftToggle
|
|
})
|
|
let buttonTheme = []
|
|
if (currentLayout === 'default') {
|
|
let addClass = button === '{shift}' ? {class: 'hg-blue2', buttons: '{shift}'} : {class: 'hg-blue2', buttons: '{lock}'}
|
|
buttonTheme = [...this.buttonTheme, addClass]
|
|
this.keyboard.setOptions({
|
|
buttonTheme: buttonTheme
|
|
})
|
|
} else if (currentLayout === 'shift') {
|
|
buttonTheme = [...this.buttonTheme]
|
|
this.keyboard.setOptions({
|
|
buttonTheme: buttonTheme
|
|
})
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
input (input) {
|
|
this.keyboard.setInput(input)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="stylus" scoped>
|
|
@deep: ~'>>>';
|
|
.hg-theme-default
|
|
visibility hidden
|
|
position fixed
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 1000;
|
|
width 100%;
|
|
padding: 1em;
|
|
background-color: #eee;
|
|
box-shadow: 0 -3px 10px rgba(0,0,0,.3);
|
|
border-radius: 10px;
|
|
font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Segoe UI,Arial,Roboto,'PingFang SC',miui,'Hiragino Sans GB','Microsoft Yahei',sans-serif;
|
|
overflow visible
|
|
/deep/ .hg-rows
|
|
width: 100%;
|
|
margin: 0;
|
|
& .hg-row:not(:last-child)
|
|
margin-bottom: 0.5em;
|
|
& .hg-row
|
|
justify-content: space-around;
|
|
& .hg-row .hg-button:not(:last-child)
|
|
margin-right: 0.5em;
|
|
& .hg-button
|
|
flex: 40;
|
|
height: 2.2em;
|
|
line-height: 2.2em;
|
|
overflow: hidden;
|
|
vertical-align: middle;
|
|
border: 1px solid #ccc;
|
|
color: #333;
|
|
background-color: #fff;
|
|
box-shadow: 0 2px 2px rgba(0,0,0,.6);
|
|
border-radius: 0.35em;
|
|
font-size: 1.25em;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
-webkit-user-select: none;
|
|
-moz-user-select: none;
|
|
-ms-user-select: none;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
box-sizing: content-box;
|
|
&:active
|
|
transform: scale(.98);
|
|
color: #333;
|
|
background-color: #d4d4d4;
|
|
border-color: #8c8c8c;
|
|
&:hover
|
|
color: #333;
|
|
background-color: #d6d6d6;
|
|
border-color: #adadad;
|
|
& .hg-button-bksp
|
|
flex: 65 1 0%;
|
|
background-image: url("../images/backspace.svg");
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
background-size: 35%;
|
|
color: #fff;
|
|
background-color: #7d7d7d;
|
|
border-color: #656565;
|
|
span
|
|
color transparent
|
|
& .hg-gray
|
|
color: #fff;
|
|
background-color: #7d7d7d;
|
|
border-color: #656565;
|
|
& .hg-blue
|
|
color: #fff;
|
|
background-color: #337ab7;
|
|
border-color: #2e6da4;
|
|
& .hg-blue2
|
|
color: #fff;
|
|
background-color: #5bc0de;
|
|
border-color: #46b8da;
|
|
& .hg-button-tab
|
|
flex: 60 1 0%;
|
|
& .hg-button-lock, .hg-button-enter
|
|
flex: 80 1 0%;
|
|
& .hg-button-shift, .hg-button-clear
|
|
flex: 100 1 0%;
|
|
& .hg-button-space
|
|
flex: 180 1 0%;
|
|
& .font-s
|
|
font-size .75em
|
|
opacity 0.6
|
|
/deep/ .hg-candidate-box
|
|
height 40px
|
|
color #000
|
|
</style>
|