Initial commit of akmon project
This commit is contained in:
168
components/picker-date/picker-date.uvue
Normal file
168
components/picker-date/picker-date.uvue
Normal file
@@ -0,0 +1,168 @@
|
||||
<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 years" :key="index"><text class="text">{{item}}年</text></view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="picker-view-column">
|
||||
<view class="item" v-for="(item,index) in months" :key="index"><text class="text">{{item}}月</text>
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="picker-view-column">
|
||||
<view class="item" v-for="(item,index) in days" :key="index"><text class="text">{{item}}日</text></view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
export default {
|
||||
name: 'PickerDate',
|
||||
props: {
|
||||
startYear: { type: Number, default: 1970 },
|
||||
endYear: { type: Number, default: 2030 },
|
||||
value: { type: [Array, String], default: () => new Date().toISOString().split('T')[0] } // 支持数组 [year, month, day] 或字符串 "2025-06-09"
|
||||
},
|
||||
data() {
|
||||
// 不能直接 this.startYear,需本地变量
|
||||
const localStartYear = 1970;
|
||||
const localEndYear = 2030;
|
||||
const years : number[] = [];
|
||||
const months : number[] = [];
|
||||
const days : number[] = [];
|
||||
for (let i = localStartYear; i <= localEndYear; i++) years.push(i);
|
||||
for (let i = 1; i <= 12; i++) months.push(i);
|
||||
for (let i = 1; i <= 31; i++) days.push(i);
|
||||
|
||||
// 获取当前日期作为默认值
|
||||
const now = new Date();
|
||||
const currentYear = now.getFullYear();
|
||||
const currentMonth = now.getMonth() + 1;
|
||||
const currentDay = now.getDate();
|
||||
|
||||
let yearIdx = years.indexOf(currentYear);
|
||||
let monthIdx = months.indexOf(currentMonth);
|
||||
let dayIdx = days.indexOf(currentDay);
|
||||
|
||||
if (yearIdx < 0) yearIdx = 0;
|
||||
if (monthIdx < 0) monthIdx = 0;
|
||||
if (dayIdx < 0) dayIdx = 0;
|
||||
|
||||
return {
|
||||
years,
|
||||
months,
|
||||
days,
|
||||
pickerValue: [yearIdx, monthIdx, dayIdx],
|
||||
localStartYear,
|
||||
localEndYear,
|
||||
indicatorStyle: '',
|
||||
indicatorClass: '',
|
||||
maskStyle: 'display:none;',
|
||||
maskClass: '',
|
||||
maskTopStyle: '',
|
||||
maskBottomStyle: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 生命周期里用 props 初始化本地变量
|
||||
this.localStartYear = this.startYear;
|
||||
this.localEndYear = this.endYear;
|
||||
// 重新生成 years
|
||||
this.years = [];
|
||||
for (let i = this.localStartYear; i <= this.localEndYear; i++) this.years.push(i);
|
||||
|
||||
// 解析传入的日期值
|
||||
const [y, m, d] = this.parseValue(this.value);
|
||||
let yearIdx = this.years.indexOf(y);
|
||||
let monthIdx = this.months.indexOf(m);
|
||||
let dayIdx = this.days.indexOf(d);
|
||||
if (yearIdx < 0) yearIdx = 0;
|
||||
if (monthIdx < 0) monthIdx = 0;
|
||||
if (dayIdx < 0) dayIdx = 0;
|
||||
this.pickerValue = [yearIdx, monthIdx, dayIdx];
|
||||
},
|
||||
mounted() {
|
||||
// 防止 picker-view-column 渲染时未能正确获取当前项,强制刷新 pickerValue
|
||||
this.$nextTick(() => {
|
||||
this.pickerValue = [...this.pickerValue];
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
value(val : any) {
|
||||
const [y, m, d] = this.parseValue(val);
|
||||
let yearIdx = this.years.indexOf(y);
|
||||
let monthIdx = this.months.indexOf(m);
|
||||
let dayIdx = this.days.indexOf(d);
|
||||
if (yearIdx < 0) yearIdx = 0;
|
||||
if (monthIdx < 0) monthIdx = 0;
|
||||
if (dayIdx < 0) dayIdx = 0;
|
||||
this.pickerValue = [yearIdx, monthIdx, dayIdx];
|
||||
}
|
||||
},
|
||||
methods: { // 解析日期值,支持数组和字符串格式
|
||||
parseValue(value : any) : number[] {
|
||||
if (Array.isArray(value)) {
|
||||
const valueArray = value as any[];
|
||||
const year : number = valueArray.length > 0 && typeof valueArray[0] === 'number' ? (valueArray[0] as number) : new Date().getFullYear();
|
||||
const month : number = valueArray.length > 1 && typeof valueArray[1] === 'number' ? (valueArray[1] as number) : (new Date().getMonth() + 1);
|
||||
const day : number = valueArray.length > 2 && typeof valueArray[2] === 'number' ? (valueArray[2] as number) : new Date().getDate();
|
||||
return [year, month, day];
|
||||
} else if (typeof value === 'string' && value.includes('-')) {
|
||||
const parts = value.split('-');
|
||||
const year = parseInt(parts[0]);
|
||||
const month = parseInt(parts[1]);
|
||||
const day = parseInt(parts[2]);
|
||||
const now = new Date();
|
||||
return [
|
||||
isNaN(year) ? now.getFullYear() : year,
|
||||
isNaN(month) ? (now.getMonth() + 1) : month,
|
||||
isNaN(day) ? now.getDate() : day
|
||||
];
|
||||
} else {
|
||||
// 默认返回当前日期
|
||||
const now = new Date();
|
||||
return [now.getFullYear(), now.getMonth() + 1, now.getDate()];
|
||||
}
|
||||
},
|
||||
|
||||
onChange(e : UniPickerViewChangeEvent) {
|
||||
const idxs = e.detail.value;
|
||||
const y = this.years[idxs[0]];
|
||||
const m = this.months[idxs[1]];
|
||||
const maxDay = new Date(y, m, 0).getDate();
|
||||
let d = this.days[idxs[2]];
|
||||
if (d > maxDay) d = maxDay;
|
||||
// 返回字符串格式的日期
|
||||
const monthStr = m < 10 ? '0' + m.toString() : m.toString();
|
||||
const dayStr = d < 10 ? '0' + d.toString() : d.toString();
|
||||
const formattedDate = `${y}-${monthStr}-${dayStr}`;
|
||||
this.$emit('change', formattedDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.picker-view {
|
||||
width: 750rpx;
|
||||
height: 320rpx;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.picker-view-column {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 50px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.text {
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user