purchase-let/uni_modules/zy-passwordboard/components/zy-passwordboard/zy-passwordboard.vue

180 lines
3.9 KiB
Vue
Raw Normal View History

2024-06-21 11:40:32 +08:00
<script setup lang="ts">
import { defineProps, defineEmits, ref, watch, computed } from 'vue';
const props = defineProps({
visible: { type: Boolean, default: () => true },
random: { type: Boolean, default: () => true },
num: { type: Number, default: () => 6 },
title: { type: String }
});
const emits = defineEmits<{
(event : 'update:visible', value : boolean);
(event : 'complete', value : string);
(event : 'close');
}>();
const tplInputs = computed(() => {
return Array(props.num).fill(0);
});
const refKeys = ref([]);
const makeKeys = () => {
refKeys.value = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'].sort(() => (props.random ? 0.5 - Math.random() : 0)).concat('删除');
refKeys.value.splice(9, 0, '清空');
};
watch(
() => props.visible,
newValue => {
if (newValue) {
makeKeys();
}
},
{ immediate: true }
);
const refValue = ref([]);
const handleKeyClick = (key : string | number) => {
switch (key.toLowerCase()) {
case '清空':
refValue.value = [];
break;
case '删除':
refValue.value.pop();
break;
default:
if (refValue.value.length < props.num) {
refValue.value.push(key);
}
break;
}
2024-06-26 14:32:27 +08:00
uni.vibrateShort();
2024-06-21 11:40:32 +08:00
if (refValue.value.length === props.num) {
emits('complete', refValue.value.join(''));
}
};
const handleClose = $event => {
handleKeyClick('c');
emits('update:visible', false);
emits('close');
};
</script>
<template>
<uni-transition :show="props.visible">
<view class="zy-passwordboard" @click="handleClose">
<uni-transition :show="props.visible">
<view class="zy-passwordboard__board" @click.stop>
<uni-transition :mode-class="['slide-bottom']" :show="props.visible">
<view class="title" v-if="props.title">{{ props.title }}</view>
<view class="inputs">
<view class="input" v-for="(input, inputi) in tplInputs" :key="inputi"><text class="text"
:class="{ filled: refValue[inputi] }"></text></view>
</view>
<view class="keys">
<view class="key" v-for="key in refKeys" :key="key">
<text class="text" :class="[`key-${key}`]" @click="handleKeyClick(key)">{{ key }}</text>
</view>
</view>
</uni-transition>
</view>
</uni-transition>
</view>
</uni-transition>
</template>
<style lang="scss">
view,
text {
box-sizing: border-box;
}
.zy-passwordboard {
box-sizing: border-box;
position: fixed;
z-index: 999;
top: 0;
bottom: 0;
bottom: constant(safe-area-inset-bottom);
bottom: env(safe-area-inset-bottom);
left: 0;
right: 0;
background-color: var(--bg-color, rgba(0, 0, 0, 0.3));
&__board {
position: absolute;
left: 0;
right: 0;
bottom: 0;
// padding: 10rpx;
background-color: white;
backdrop-filter: blur(2rpx);
border-radius: 30rpx 30rpx 0 0;
.title {
padding: 20rpx;
text-align: center;
color: #000000;
font-size: 35rpx;
padding-bottom: 0;
}
.inputs {
display: flex;
justify-content: center;
padding-top: 40rpx;
margin-bottom: 40rpx;
.input {
padding: 10rpx;
.text {
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
background-color: #ffffff;
border-radius: 20rpx;
background-color: #E6E6E6;
&.filled:before {
content: '';
width: 30%;
height: 30%;
border-radius: 50%;
background-color: #000000;
}
}
}
}
.keys {
width: 101vw;
display: flex;
flex-wrap: wrap;
background-color: white;
.key {
flex: 0 1 33%;
padding: 10rpx;
border: 1px solid #E6E6E6;
.text {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding: 20rpx 10rpx;
background-color: #ffffff;
border-radius: 20rpx;
font-size: 34rpx;
font-weight: bold;
&.key- {
opacity: 1;
}
}
}
}
}
}
</style>