Files
akmon/components/picker-time/picker-time.uvue
2026-01-20 08:04:15 +08:00

105 lines
2.8 KiB
Plaintext

<template>
<view>
<picker-view
class="picker-view"
:value="pickerValue"
@change="onChange"
:indicator-style="indicatorStyle"
:indicator-class="indicatorClass"
:mask-style="maskStyle"
:mask-class="maskClass"
:mask-top-style="maskTopStyle"
:mask-bottom-style="maskBottomStyle"
>
<picker-view-column class="picker-view-column">
<view class="item" v-for="(item ,index) in hours" :key="index">
<text class="text">{{(item as number) < 10 ? '0' + item : item}}时</text>
</view>
</picker-view-column>
<picker-view-column class="picker-view-column">
<view class="item" v-for="(item,index) in minutes" :key="index">
<text class="text">{{(item as number) < 10 ? '0' + item : item}}分</text>
</view>
</picker-view-column>
<picker-view-column v-if="showSecond" class="picker-view-column">
<view class="item" v-for="(item,index) in seconds" :key="index">
<text class="text">{{(item as number) < 10 ? '0' + item : item}}秒</text>
</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script setup lang="uts">
import { ref, watch } from 'vue'
const props = defineProps({
value: { type: Array, default: () => [12, 0, 0] }, // [hour, minute, second]
showSecond: { type: Boolean, default: false }
})
const emit = defineEmits(['change'])
const hours = Array.from({ length: 24 }, (_, i) => i)
const minutes = Array.from({ length: 60 }, (_, i) => i)
const seconds = Array.from({ length: 60 }, (_, i) => i)
const pickerValue = ref<number[]>([])
const updatePickerValue = (val: number[]) => {
const h = val[0] ?? 12
const m = val[1] ?? 0
const s = val[2] ?? 0
let hourIdx = hours.indexOf(h)
let minuteIdx = minutes.indexOf(m)
let secondIdx = seconds.indexOf(s)
if (hourIdx < 0) hourIdx = 0
if (minuteIdx < 0) minuteIdx = 0
if (secondIdx < 0) secondIdx = 0
pickerValue.value = props.showSecond ? [hourIdx, minuteIdx, secondIdx] : [hourIdx, minuteIdx]
}
watch(props.value, (val:number[]) => {
updatePickerValue(val)
return
}, { immediate: true })
const indicatorStyle = 'height: 50px;'
const indicatorClass = ''
const maskStyle = ''
const maskClass = ''
const maskTopStyle = ''
const maskBottomStyle = ''
const onChange = (e: UniPickerViewChangeEvent) => {
const idxs = e.detail.value
const h = hours[idxs[0]]
const m = minutes[idxs[1]]
if (props.showSecond) {
const s = seconds[idxs[2]]
emit('change', [h, m, s])
} else {
emit('change', [h, m])
}
}
</script>
<style scoped>
.picker-view {
width: 750rpx;
height: 220px;
margin-top: 10px;
margin-bottom: 20px;
}
.picker-view-column {
width: 300rpx;
}
.item {
height: 50px;
}
.text {
line-height: 50px;
text-align: center;
}
</style>