numPad.vue
<template>
<div class="num-pad" :class="{ 'num-pad--visible': visible }">
<div class="num-pad__header" v-if="withHeader">
<span>{{ header }}</span>
<button class="num-pad__close" @click="handleClose">X</button>
</div>
<div class="num-pad__body">
<div v-for="(row, index) in rows" :key="index" class="num-pad__row">
<div v-for="(num, index) in row" :key="index" class="num-pad__item" @click="handleClick(num)">
{{ num }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'NumPad',
props: {
value: [Number, String],
point: Boolean,
withHeader: Boolean,
header: String,
visible: Boolean
},
data() {
return {
rows: [],
canDelete: false
}
},
created() {
// 初始化数字键盘
this.initRows();
},
methods: {
initRows() {
const { point } = this;
if (point) {
this.rows = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
['.', 0, '<']
];
} else {
this.rows = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
['', 0, '<']
];
}
},
handleClick(num) {
const { canDelete } = this;
const { point } = this;
const value = this.value.toString();
if (num === '') {
return;
}
if (num === '.') {
if (!value.includes('.') && point) {
this.$emit('input', value + num);
this.canDelete = true;
}
} else if (num === '<') {
if (canDelete) {
this.$emit('input', value.slice(0, -1));
this.canDelete = value.length > 1;
}
} else if (value === '') {
this.$emit('input', num);
this.canDelete = true;
} else {
this.$emit('input', value + num);
this.canDelete = true;
}
},
handleClose() {
this.$emit('update:visible', false);
}
},
watch: {
visible(newVal) {
if (newVal) {
this.canDelete = this.value !== '';
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.num-pad {
display: flex;
flex-wrap: wrap;
width: 250px;
background-color: #fff;
box-shadow: 0 1px 5px rgba(0,0,0,.2);
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
transition: all .3s ease-out;
z-index: 10;
opacity: 0;
&.num-pad--visible {
transform: translateX(-50%) translateY(-100%);
opacity: 1;
}
.num-pad__header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
height: 40px;
width: 100%;
font-size: 18px;
border-bottom: 1px solid #ccc;
background-color: #f6f7f9;
}
.num-pad__body {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
height: 250px;
width: 100%;
padding: 10px;
}
.num-pad__row {
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 10px;
}
.num-pad__item {
width: 30%;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ccc;
font-size: 24px;
cursor: pointer;
&:active {
background-color: #f6f7f9;
}
}
.num-pad__close {
font-size: 24px;
color: #999;
border: none;
background-color: transparent;
cursor: pointer;
&:focus,
&:hover {
color: #444;
}
}
}
</style>
使用 <num-pad v-model="form.number" :visible.sync="numPadVisible" point withHeader header="请输入数量" />