效果图
![](https://i-blog.csdnimg.cn/blog_migrate/77a4b838198b1b15122f9604541c835e.png)
代码
<template>
<div class="virtual-keyboard" v-show="this.showKeyboary">
<input type="text" :value="value" readonly>
<div class="keyboard">
<button v-for="num in numbers" :key="num" @click="appendToDisplay(num)" class="key">{{ num }}</button>
<button @click="appendToDisplay('.')" class="key">.</button>
<button @click="clearDisplay" class="key">清空</button>
<button @click="backspace" class="key">回退</button>
<button @click="cancel" class="key">取消</button>
<button @click="confirmInput" class="confirm-key">确定</button>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
},
showKeyboary: {
type: Boolean,
default: false
}
},
methods: {
appendToDisplay(char) {
if (char === '.' && this.value.includes('.')) {
return
}
this.$emit('input', this.value + char)
},
clearDisplay() {
this.$emit('input', '')
},
cancel() {
this.$emit('cancel', this.value)
},
confirmInput() {
this.$emit('confirmInput', this.value)
},
backspace() {
this.$emit('input', this.value.slice(0, -1))
}
},
computed: {
numbers() {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
}
}
}
</script>
<style scoped>
.virtual-keyboard {
width: 200px;
margin: 20px auto;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
background: #222222;
position: absolute;
top: 150px;
left: 290px;
z-index: 9999;
}
input[type="text"] {
width: calc(100% - 15px);
margin-bottom: 10px;
padding: 5px;
}
.keyboard {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 5px;
}
.key {
width: 100%;
height: 40px;
border: none;
background-color: #f0f0f0;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.key:hover {
background-color: #e0e0e0;
}
.confirm-key {
//grid-column: span 1;
background-color: #007bff;
border: 0;
cursor: pointer;
color: #fff;
border-radius: 4px;
}
.confirm-key:hover {
background-color: #007bff;
}
</style>