vue3 ts 写一个滑动选择的日期选择器组件

DatePicker.vue
<template>
<div class="date-picker-container">
<div class="date-picker">
<select v-model="selectedYear" @change="updateDays">
<option value="">Year</option>
<option v-for="year in years" :key="year" :value="year">{{ year }}</option>
</select>
-
<select v-model="selectedMonth" @change="updateDays">
<option value="">Month</option>
<option v-for="month in months" :key="month" :value="month">
{{ String(month).padStart(2, "0") }}
</option>
-
</select>
-
<select v-model="selectedDay">
<option value="">Day</option>
<option v-for="day in days" :key="day" :value="day">
{{ String(day).padStart(2, "0") }}
</option>
</select>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, watch, onMounted } from "vue";
const props = defineProps({
modelValue: {
type: String,
default: "",
},
});
const emit = defineEmits(["update:modelValue"]);
const years = ref<number[]>([]);
const months = ref<number[]>([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
const days = ref<number[]>([]);
const selectedYear = ref<string>("");
const selectedMonth = ref<string>("");
const selectedDay = ref<string>("");
const currentYear = new Date().getFullYear();
years.value = Array.from({ length: 150 }, (_, i) => currentYear - 100 + i);
const updateDays = () => {
if (!selectedYear.value || !selectedMonth.value) {
days.value = [];
return;
}
const year = parseInt(selectedYear.value, 10);
const month = parseInt(selectedMonth.value, 10);
const daysInMonth = new Date(year, month, 0).getDate();
days.value = Array.from({ length: daysInMonth }, (_, i) => i + 1);
};
const selectedDate = computed(() => {
if (selectedYear.value && selectedMonth.value && selectedDay.value) {
return `${selectedYear.value}-${String(selectedMonth.value).padStart(
2,
"0"
)}-${String(selectedDay.value).padStart(2, "0")}`;
}
return "";
});
// 初始化值
onMounted(() => {});
// 改进的初始化函数
const initFromDateString = (dateStr: string) => {
if (!dateStr) return;
// 尝试解析各种可能的日期格式
const parts = dateStr.split("-");
if (parts.length === 3) {
selectedYear.value = parts[0];
// 检查 parts[1] 是否以 '0' 开头
if (parts[1].startsWith("0")) {
// 转换为数字
selectedMonth.value = Number(parts[1]).toString(); // 或 +parts[1] 或 Number(parts[1])
} else {
// 如果不以 '0' 开头,保持原样或进行其他处理
selectedMonth.value = parts[1];
}
if (parts[2].startsWith("0")) {
// 转换为数字
selectedDay.value = Number(parts[2]).toString(); // 或 +parts[1] 或 Number(parts[1])
} else {
// 如果不以 '0' 开头,保持原样或进行其他处理
selectedDay.value = parts[2];
}
}
updateDays();
};
// 监听 modelValue 变化
watch(
() => props.modelValue,
(newVal) => {
initFromDateString(newVal);
},
{ immediate: true }
);
// 监听选择的变化
watch(
[selectedYear, selectedMonth, selectedDay],
() => {
const dateStr = selectedDate.value;
emit("update:modelValue", dateStr);
},
{ immediate: true }
);
</script>
<style scoped>
.date-picker-container {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}
.date-picker {
display: flex;
gap: 10px;
}
select {
width: 33%;
padding: 5px;
font-size: 16px;
border-radius: 5px;
border: 1px solid #dcdfe6;
background-color: #fff;
color: #606266;
}
</style>
在需要的地方引入
<template>
<DatePicker v-model="ruleForm.Dateofbirth" />
<template>
...
<script lang="ts" setup name="FormInfo">
import DatePicker from "./DatePicker.vue";
</script>