完成团课列表页面布局以及基础交互,使用测试数据
This commit is contained in:
@@ -0,0 +1,728 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 时间范围选择弹窗 -->
|
||||
<Transition name="modal">
|
||||
<view v-if="visible" class="time-range-modal">
|
||||
<view class="modal-mask" @click="handleClose"></view>
|
||||
<view class="modal-content">
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">选择时间范围</text>
|
||||
<view class="header-actions">
|
||||
<text class="modal-clear" @click="handleClear">清空</text>
|
||||
<text class="modal-close" @click="handleClose">×</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="modal-body">
|
||||
<!-- 开始日期 -->
|
||||
<view class="date-item">
|
||||
<text class="date-label">开始日期</text>
|
||||
<view class="date-value" @click="toggleStartPicker">
|
||||
<text>{{ localStartDate || '请选择' }}</text>
|
||||
<text class="date-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 结束日期 -->
|
||||
<view class="date-item">
|
||||
<text class="date-label">结束日期</text>
|
||||
<view class="date-value" @click="toggleEndPicker">
|
||||
<text>{{ localEndDate || '请选择' }}</text>
|
||||
<text class="date-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 快捷选择 -->
|
||||
<view class="quick-select">
|
||||
<text class="quick-label">快捷选择</text>
|
||||
<view class="quick-btns">
|
||||
<view
|
||||
v-for="item in quickOptions"
|
||||
:key="item.value"
|
||||
class="quick-btn"
|
||||
:class="{ active: quickSelected === item.value }"
|
||||
@click="applyQuickOption(item.value)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="modal-footer">
|
||||
<view class="btn btn-cancel" @click="handleClose">取消</view>
|
||||
<view class="btn btn-confirm" @click="handleConfirm">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 日期选择器弹窗 -->
|
||||
<Transition name="date-picker">
|
||||
<view v-if="showDatePicker" class="date-picker-modal">
|
||||
<view class="date-mask" @click="showDatePicker = false"></view>
|
||||
<view class="date-picker-content">
|
||||
<view class="date-header">
|
||||
<text class="date-prev" @click="prevMonth">‹</text>
|
||||
<text class="date-title">{{ currentYear }}年{{ currentMonth }}月</text>
|
||||
<text class="date-next" @click="nextMonth">›</text>
|
||||
</view>
|
||||
<view class="date-weekdays">
|
||||
<text v-for="day in weekdays" :key="day">{{ day }}</text>
|
||||
</view>
|
||||
<view class="date-days">
|
||||
<view
|
||||
v-for="(day, index) in calendarDays"
|
||||
:key="index"
|
||||
class="date-day"
|
||||
:class="{
|
||||
'other-month': !day.currentMonth,
|
||||
'today': day.isToday,
|
||||
'selected': day.date === selectedDate,
|
||||
'disabled': day.disabled
|
||||
}"
|
||||
@click="selectDate(day)"
|
||||
>
|
||||
{{ day.day }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Transition>
|
||||
</view>
|
||||
</Transition>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, computed, onMounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
startDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
endDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:visible', 'update:startDate', 'update:endDate', 'confirm', 'cancel'])
|
||||
|
||||
const localStartDate = ref(props.startDate)
|
||||
const localEndDate = ref(props.endDate)
|
||||
const showDatePicker = ref(false)
|
||||
const pickerType = ref('start') // 'start' | 'end'
|
||||
const currentYear = ref(2024)
|
||||
const currentMonth = ref(1)
|
||||
const selectedDate = ref('')
|
||||
const quickSelected = ref('')
|
||||
|
||||
const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
||||
|
||||
const quickOptions = [
|
||||
{ label: '近7天', value: '7d' },
|
||||
{ label: '近30天', value: '30d' },
|
||||
{ label: '本月', value: 'month' },
|
||||
{ label: '上月', value: 'lastMonth' }
|
||||
]
|
||||
|
||||
// 监听 props 变化
|
||||
watch(() => props.startDate, (val) => {
|
||||
localStartDate.value = val
|
||||
})
|
||||
|
||||
watch(() => props.endDate, (val) => {
|
||||
localEndDate.value = val
|
||||
})
|
||||
|
||||
watch(() => props.visible, (val) => {
|
||||
if (val) {
|
||||
// 弹窗打开时设置当前日期
|
||||
const now = new Date()
|
||||
currentYear.value = now.getFullYear()
|
||||
currentMonth.value = now.getMonth() + 1
|
||||
}
|
||||
})
|
||||
|
||||
// 计算时间范围文本
|
||||
const timeRangeText = computed(() => {
|
||||
if (localStartDate.value && localEndDate.value) {
|
||||
return `${localStartDate.value} 至 ${localEndDate.value}`
|
||||
} else if (localStartDate.value) {
|
||||
return `${localStartDate.value} 起`
|
||||
} else if (localEndDate.value) {
|
||||
return `至 ${localEndDate.value}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
// 生成日历日期
|
||||
const calendarDays = computed(() => {
|
||||
const days = []
|
||||
const firstDay = new Date(currentYear.value, currentMonth.value - 1, 1)
|
||||
const lastDay = new Date(currentYear.value, currentMonth.value, 0)
|
||||
const startDay = firstDay.getDay()
|
||||
const totalDays = lastDay.getDate()
|
||||
|
||||
// 上个月的天数
|
||||
const prevMonthLastDay = new Date(currentYear.value, currentMonth.value - 1, 0).getDate()
|
||||
for (let i = startDay - 1; i >= 0; i--) {
|
||||
days.push({
|
||||
day: prevMonthLastDay - i,
|
||||
date: formatDate(currentYear.value, currentMonth.value - 1, prevMonthLastDay - i),
|
||||
currentMonth: false,
|
||||
isToday: false,
|
||||
disabled: true
|
||||
})
|
||||
}
|
||||
|
||||
// 本月的天数
|
||||
const today = new Date()
|
||||
for (let i = 1; i <= totalDays; i++) {
|
||||
const dateStr = formatDate(currentYear.value, currentMonth.value, i)
|
||||
days.push({
|
||||
day: i,
|
||||
date: dateStr,
|
||||
currentMonth: true,
|
||||
isToday: isToday(currentYear.value, currentMonth.value, i),
|
||||
disabled: isFuture(currentYear.value, currentMonth.value, i)
|
||||
})
|
||||
}
|
||||
|
||||
// 下个月的天数
|
||||
const remaining = 42 - days.length
|
||||
for (let i = 1; i <= remaining; i++) {
|
||||
days.push({
|
||||
day: i,
|
||||
date: formatDate(currentYear.value, currentMonth.value + 1, i),
|
||||
currentMonth: false,
|
||||
isToday: false,
|
||||
disabled: true
|
||||
})
|
||||
}
|
||||
|
||||
return days
|
||||
})
|
||||
|
||||
// 格式化日期
|
||||
function formatDate(year, month, day) {
|
||||
const m = month.toString().padStart(2, '0')
|
||||
const d = day.toString().padStart(2, '0')
|
||||
return `${year}-${m}-${d}`
|
||||
}
|
||||
|
||||
// 判断是否是今天
|
||||
function isToday(year, month, day) {
|
||||
const today = new Date()
|
||||
return year === today.getFullYear() &&
|
||||
month === today.getMonth() + 1 &&
|
||||
day === today.getDate()
|
||||
}
|
||||
|
||||
// 判断是否是未来日期
|
||||
function isFuture(year, month, day) {
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
const date = new Date(year, month - 1, day)
|
||||
return date > today
|
||||
}
|
||||
|
||||
// 切换日期选择器
|
||||
const toggleStartPicker = () => {
|
||||
pickerType.value = 'start'
|
||||
selectedDate.value = localStartDate.value
|
||||
showDatePicker.value = true
|
||||
}
|
||||
|
||||
const toggleEndPicker = () => {
|
||||
pickerType.value = 'end'
|
||||
selectedDate.value = localEndDate.value
|
||||
showDatePicker.value = true
|
||||
}
|
||||
|
||||
// 月份切换
|
||||
const prevMonth = () => {
|
||||
if (currentMonth.value === 1) {
|
||||
currentYear.value--
|
||||
currentMonth.value = 12
|
||||
} else {
|
||||
currentMonth.value--
|
||||
}
|
||||
}
|
||||
|
||||
const nextMonth = () => {
|
||||
if (currentMonth.value === 12) {
|
||||
currentYear.value++
|
||||
currentMonth.value = 1
|
||||
} else {
|
||||
currentMonth.value++
|
||||
}
|
||||
}
|
||||
|
||||
// 选择日期
|
||||
const selectDate = (day) => {
|
||||
if (day.disabled) return
|
||||
selectedDate.value = day.date
|
||||
if (pickerType.value === 'start') {
|
||||
localStartDate.value = day.date
|
||||
emit('update:startDate', day.date)
|
||||
} else {
|
||||
localEndDate.value = day.date
|
||||
emit('update:endDate', day.date)
|
||||
}
|
||||
showDatePicker.value = false
|
||||
console.log(`[TimeRangePicker] ${pickerType.value === 'start' ? '开始' : '结束'}日期变更:`, day.date)
|
||||
}
|
||||
|
||||
// 应用快捷选项
|
||||
const applyQuickOption = (value) => {
|
||||
quickSelected.value = value
|
||||
const today = new Date()
|
||||
let startDate, endDate
|
||||
|
||||
switch (value) {
|
||||
case '7d':
|
||||
startDate = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
endDate = today
|
||||
break
|
||||
case '30d':
|
||||
startDate = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000)
|
||||
endDate = today
|
||||
break
|
||||
case 'month':
|
||||
startDate = new Date(today.getFullYear(), today.getMonth(), 1)
|
||||
endDate = today
|
||||
break
|
||||
case 'lastMonth':
|
||||
startDate = new Date(today.getFullYear(), today.getMonth() - 1, 1)
|
||||
endDate = new Date(today.getFullYear(), today.getMonth(), 0)
|
||||
break
|
||||
}
|
||||
|
||||
localStartDate.value = formatDate(startDate.getFullYear(), startDate.getMonth() + 1, startDate.getDate())
|
||||
localEndDate.value = formatDate(endDate.getFullYear(), endDate.getMonth() + 1, endDate.getDate())
|
||||
emit('update:startDate', localStartDate.value)
|
||||
emit('update:endDate', localEndDate.value)
|
||||
console.log('[TimeRangePicker] 快捷选择:', value, { start: localStartDate.value, end: localEndDate.value })
|
||||
}
|
||||
|
||||
// 清空选择
|
||||
const handleClear = () => {
|
||||
localStartDate.value = ''
|
||||
localEndDate.value = ''
|
||||
quickSelected.value = ''
|
||||
emit('update:startDate', '')
|
||||
emit('update:endDate', '')
|
||||
console.log('[TimeRangePicker] 已清空时间选择')
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
console.log('[TimeRangePicker] 关闭时间选择器')
|
||||
emit('update:visible', false)
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
// 确认选择
|
||||
const handleConfirm = () => {
|
||||
console.log('[TimeRangePicker] 确认时间范围:', {
|
||||
startDate: localStartDate.value,
|
||||
endDate: localEndDate.value,
|
||||
timeRangeText: timeRangeText.value
|
||||
})
|
||||
emit('update:visible', false)
|
||||
emit('confirm', {
|
||||
startDate: localStartDate.value,
|
||||
endDate: localEndDate.value,
|
||||
timeRangeText: timeRangeText.value
|
||||
})
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
const getTimeRangeParams = () => {
|
||||
const params = {
|
||||
startDate: localStartDate.value,
|
||||
endDate: localEndDate.value,
|
||||
timeRangeText: timeRangeText.value
|
||||
}
|
||||
console.log('[TimeRangePicker] 获取时间范围参数:', params)
|
||||
return params
|
||||
}
|
||||
|
||||
// 重置日期
|
||||
const resetDate = () => {
|
||||
localStartDate.value = ''
|
||||
localEndDate.value = ''
|
||||
quickSelected.value = ''
|
||||
emit('update:startDate', '')
|
||||
emit('update:endDate', '')
|
||||
console.log('[TimeRangePicker] 已重置日期')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getTimeRangeParams,
|
||||
resetDate,
|
||||
timeRangeText
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.time-range-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.modal-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
width: 640rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #E9EDF2;
|
||||
|
||||
.modal-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1a202c;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.modal-clear {
|
||||
font-size: 28rpx;
|
||||
color: #8A99B4;
|
||||
padding: 8rpx 16rpx;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
font-size: 48rpx;
|
||||
color: #8A99B4;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 32rpx;
|
||||
|
||||
.date-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid #F0F2F5;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.date-label {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.date-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #1a202c;
|
||||
}
|
||||
|
||||
.date-arrow {
|
||||
font-size: 32rpx;
|
||||
color: #C4C9D4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.quick-select {
|
||||
margin-top: 24rpx;
|
||||
|
||||
.quick-label {
|
||||
font-size: 26rpx;
|
||||
color: #9CA3AF;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.quick-btns {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
|
||||
.quick-btn {
|
||||
padding: 16rpx 28rpx;
|
||||
background: #F5F7FA;
|
||||
border-radius: 32rpx;
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
|
||||
&.active {
|
||||
background: #FF6B35;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
border-top: 1rpx solid #E9EDF2;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
|
||||
&.btn-cancel {
|
||||
color: #6B7280;
|
||||
border-right: 1rpx solid #E9EDF2;
|
||||
}
|
||||
|
||||
&.btn-confirm {
|
||||
color: #FF6B35;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.date-picker-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1001;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
.date-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.date-picker-content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
transform: translateY(0);
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
.date-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
|
||||
.date-prev, .date-next {
|
||||
font-size: 40rpx;
|
||||
color: #1a202c;
|
||||
width: 64rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.date-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1a202c;
|
||||
}
|
||||
}
|
||||
|
||||
.date-weekdays {
|
||||
display: flex;
|
||||
padding: 0 24rpx;
|
||||
|
||||
text {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: #9CA3AF;
|
||||
padding: 16rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.date-days {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 16rpx 24rpx 32rpx;
|
||||
|
||||
.date-day {
|
||||
width: calc(100% / 7);
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
color: #1a202c;
|
||||
border-radius: 50%;
|
||||
|
||||
&.other-month {
|
||||
color: #D1D5DB;
|
||||
}
|
||||
|
||||
&.today {
|
||||
background: #F5F7FA;
|
||||
color: #FF6B35;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background: #FF6B35;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #E5E7EB;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 居中弹窗进入动画 */
|
||||
.modal-enter-active {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.modal-enter-active .modal-mask {
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-enter-active .modal-content {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.modal-enter-from .modal-mask {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.modal-enter-from .modal-content {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
/* 居中弹窗退出动画 */
|
||||
.modal-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.modal-leave-active .modal-mask {
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-leave-active .modal-content {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.modal-leave-to .modal-mask {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.modal-leave-to .modal-content {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
@keyframes modalIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 日期选择器进入动画 */
|
||||
.date-picker-enter-active {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.date-picker-enter-active .date-mask {
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.date-picker-enter-active .date-picker-content {
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.date-picker-enter-from .date-mask {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.date-picker-enter-from .date-picker-content {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
/* 日期选择器退出动画 */
|
||||
.date-picker-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.date-picker-leave-active .date-mask {
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.date-picker-leave-active .date-picker-content {
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.date-picker-leave-to .date-mask {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.date-picker-leave-to .date-picker-content {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user