185 lines
3.7 KiB
Vue
185 lines
3.7 KiB
Vue
<template>
|
||
<view class="y-f" style="height: 55vh">
|
||
<view class="weight">
|
||
<view class="weight-data">{{ nums }}</view>
|
||
</view>
|
||
|
||
<view class="keyboard-container">
|
||
<view class="keypad">
|
||
<view
|
||
class="oner"
|
||
:style="getListItemStyle(index)"
|
||
v-for="(item, index) in numbers"
|
||
:key="'num_' + index"
|
||
@click="changeNums(item, index)"
|
||
>
|
||
{{ item.text }}
|
||
</view>
|
||
</view>
|
||
<view class="func-pad">
|
||
<view @click="jianshao()" class="oner flex1">
|
||
<u-icon name="arrow-leftward" bold></u-icon>
|
||
</view>
|
||
<view @click="setNull()" class="oner flex1 mt10 mb10">清空</view>
|
||
<view class="oner confirm" @click="ok()">确认</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed } from 'vue'
|
||
|
||
// Props
|
||
const props = defineProps({
|
||
numKeyboardParam: {
|
||
type: Object,
|
||
default: () => null
|
||
}
|
||
})
|
||
|
||
// Emits(虽然你用的是 uni.$emit,但也可以定义 emit 用于规范)
|
||
// const emit = defineEmits(['keyboardOK'])
|
||
|
||
// Data
|
||
const nums = ref('')
|
||
const numbers = ref([
|
||
{ text: '1' },
|
||
{ text: '2' },
|
||
{ text: '3' },
|
||
{ text: '4' },
|
||
{ text: '5' },
|
||
{ text: '6' },
|
||
{ text: '7' },
|
||
{ text: '8' },
|
||
{ text: '9' },
|
||
{ text: '0' },
|
||
{ text: '-' },
|
||
{ text: '.' }
|
||
])
|
||
|
||
// Methods
|
||
const ok = () => {
|
||
const val = { val: nums.value }
|
||
nums.value = ''
|
||
if (val.val) {
|
||
uni.$emit('keyboardOK', val)
|
||
}
|
||
}
|
||
|
||
const setNull = () => {
|
||
nums.value = ''
|
||
uni.$emit('keyboardOK', null)
|
||
}
|
||
const clearNum = () => {
|
||
nums.value = ''
|
||
}
|
||
const jianshao = () => {
|
||
if (nums.value) {
|
||
nums.value = nums.value.substring(0, nums.value.length - 1)
|
||
}
|
||
}
|
||
|
||
const changeNums = (item, index) => {
|
||
const inputChar = item.text
|
||
// 处理负号 '-'
|
||
if (inputChar === '-') {
|
||
// 只允许在输入为空时输入负号(即只能作为第一个字符)
|
||
if (nums.value === '') {
|
||
nums.value = '-'
|
||
}
|
||
return // 无论是否成功,都不继续处理
|
||
}
|
||
if (inputChar === '.') {
|
||
// 不能以 '.' 开头(除非已有负号)
|
||
if (nums.value === '' || nums.value === '-') {
|
||
return false
|
||
}
|
||
// 已存在小数点则不允许再输入
|
||
if (nums.value.indexOf('.') !== -1) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
// 检查小数位数限制
|
||
let decimal = props.numKeyboardParam?.decimal ?? -1
|
||
const parts = nums.value.split('.')
|
||
if (parts.length === 2 && decimal !== -1) {
|
||
if (parts[1].length >= decimal) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
nums.value += inputChar
|
||
}
|
||
|
||
const getListItemStyle = index => {
|
||
return {
|
||
background: numbers.value[index]?.background || ''
|
||
}
|
||
}
|
||
defineExpose({ clearNum })
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.keyboard-container {
|
||
flex: 5;
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: rgba(232, 232, 232, 0.98);
|
||
}
|
||
.keypad {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
grid-auto-rows: 1fr;
|
||
gap: 10px;
|
||
padding: 10px;
|
||
flex: 4;
|
||
height: 95%;
|
||
}
|
||
|
||
.oner {
|
||
width: 95%;
|
||
font-size: 20px;
|
||
border: none;
|
||
border-radius: 5px;
|
||
background-color: #ffffff;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.func-pad {
|
||
height: 100%;
|
||
display: flex;
|
||
padding: 10px 10px 10px 0;
|
||
flex-direction: column;
|
||
flex: 1;
|
||
box-sizing: border-box;
|
||
}
|
||
.confirm {
|
||
flex: 2;
|
||
color: #ffffff;
|
||
background-color: #19be6b;
|
||
}
|
||
.weight {
|
||
width: 100%;
|
||
background-color: #2c405a;
|
||
flex: 1;
|
||
padding: 8px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.weight-data {
|
||
color: #4cd964;
|
||
text-align: right;
|
||
letter-spacing: 5px;
|
||
font-size: 50px;
|
||
font-family: zzjc-lcd;
|
||
height: 40px;
|
||
}
|
||
</style>
|