先看效果图
组件XKeyboard.vue
<template>
<div id="XKeyBoard" style="display:none;" :style="{width: width+'vw',height: height+'vw',left:left+'px',top:top+'px'}" ref="XKeyBoard">
<div class="x-top">
<div @click.stop="clean"><img src="@/assets/imgs/keyborad.png" />清空</div>
<div></div>
<div><img src="@/assets/imgs/drop_down.png" @click="close()" /></div>
</div>
<div class="x-num" v-for="(ke,index) in keys" :key="index">
<div @click.stop="entry(lk)" v-for="lk in ke" :key="'k'+lk">{{lk}}</div>
</div>
</div>
</template>
<script>
export default {
name: 'XKeyBoard',
data() {
return {
left: 0,
top: 0,
target: null,
keys: [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['.', '0', 'x']
]
};
},
props: ['width', 'height'],
methods: {
// 外部输入框事件传值过来
focuss(left, top, input_height, height, width, target) {
// 展示键盘
document.getElementById('XKeyBoard').style.display = 'block';
this.target = target;
// 获取键盘的高度
let key_height = document.getElementById('XKeyBoard').clientHeight;
let key_width = document.getElementById('XKeyBoard').clientWidth;
// 判定键盘需要处于input上面还是下面
if (top < height / 2) { // input位置小于屏幕50%高度
this.top = top + input_height * 2; // 键盘位置=input顶部坐标值+input高度*2
} else { // 其他
this.top = top - input_height - key_height; // 键盘顶部坐标值=input框顶部坐标值-input高度-键盘高度
}
// 右侧超出窗口,自动调整
if (width - left < key_width) {
this.left = width - input_height - key_width; // 键盘左边坐标值=屏幕宽-input高度-键盘宽度
} else {
this.left = left + input_height; // 键盘左边坐标值=input左边坐标值-input高度
}
},
// 点击键盘事件
entry(value) {
// 匹配0-9和.对input对象内容累加
if (/^([0-9]{1})$/g.test(value) || value == '.') {
this.target.value += value;
} else { // 删除键清空input对象内容
this.target.value = this.target.value.slice(0, this.target.value.length - 1);
}
},
// 隐藏键盘自身
close() {
document.getElementById('XKeyBoard').style.display = 'none';
},
// 清空内容
clean() {
this.target.value = '';
}
}
}
</script>
<style lang="less" scoped>
// 外框位置对照浏览器窗口大小
#XKeyBoard {
position: fixed;
border: 0.1vw solid #dcdee2;
user-select: none;
color: #515a6e;
border-radius: 2px;
background: white;
z-index: 100;
// 顶部居中
.x-top {
width: 100%;
height: 11%;
display: flex;
justify-content: center;
// 所有div横向居中
div {
display: flex;
align-items: center;
img {
width: 2vw;
height: 2vw;
}
}
// 标题区向左对齐
div:nth-child(1) {
justify-content: flex-start;
width: 6vw;
}
// 空白区占据宽度
div:nth-child(2) {
width: 12vw;
}
// 关闭按钮区右对齐
div:nth-child(3) {
width: 2vw;
justify-content: flex-end;
cursor: pointer;
}
// 所有按钮触发效果
div:active {
opacity: 0.6;
background: rgb(90, 89, 89);
}
}
// 数字区宽高、盒子、框线
.x-num {
width: 100%;
height: 22.1%;
display: flex;
border-top: 1px solid #dcdee2;
// 所有按钮居中,改变鼠标样式
div {
width: 33.33%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
// 按钮触发效果
div:active {
background: rgb(90, 89, 89);
color: white;
}
}
.x-num > div:nth-child(3n + 1),
.x-num > div:nth-child(3n + 2) {
border-right: 1px solid #dcdee2;
}
}
</style>
引用
main.js
import Vue from 'vue'
import App from './App.vue'
import XKeyboard from '@/components/XKeyboard';
Vue.config.productionTip = false
Vue.component('x-keyboard',XKeyboard);
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<x-keyboard :width="21" :height="16" ref="keyboard" :left="left" :top="top"></x-keyboard>
<input @focus.stop="focuss($event)"/>
<input @focus.stop="focuss($event)"/>
<input style="position:fixed;left:0;top:50vh;" @focus.stop="focuss($event)"/>
<input style="position:fixed;right:0;top:80vh;" @focus.stop="focuss($event)"/>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
left: 0,
top: 0,
input_height: 0,
height: innerHeight,
width: innerWidth,
};
},
methods: {
// 获取焦点事件
focuss(event) {
let input_height = event.target.offsetHeight;
let left = event.target.offsetLeft;
let top = event.target.offsetTop;
// 调用键盘组件的方法,传过去input的left、top、height
// 以及(浏览器窗口高宽)、event.target(当前点击的input)
this.$refs.keyboard.focuss(left, top, input_height, this.height, this.width, event.target);
},
},
}
</script>
<style>
#app {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>