Files
YGChatCS/components/Calender/example.vue
2025-08-02 13:59:29 +08:00

253 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="calendar-example">
<!-- 页面标题 -->
<view class="page-header">
<text class="page-title">日历组件使用示例</text>
</view>
<!-- 触发器区域 -->
<view class="trigger-section">
<view class="date-input" @tap="openCalendar">
<view class="input-content">
<text class="input-label">选择日期</text>
<text class="input-value" v-if="selectedDate">{{ selectedDate }}</text>
<text class="input-placeholder" v-else>请选择日期</text>
</view>
<uni-icons type="calendar" size="20" color="#1890ff"></uni-icons>
</view>
<!-- 范围选择示例 -->
<view class="date-input" @tap="openRangeCalendar">
<view class="input-content">
<text class="input-label">选择日期范围</text>
<text class="input-value" v-if="selectedRange.start && selectedRange.end">
{{ selectedRange.start }} {{ selectedRange.end }}
</text>
<text class="input-placeholder" v-else>请选择日期范围</text>
</view>
<uni-icons type="calendar" size="20" color="#1890ff"></uni-icons>
</view>
</view>
<!-- 结果显示区域 -->
<view class="result-section" v-if="selectedDate || (selectedRange.start && selectedRange.end)">
<text class="result-title">选择结果</text>
<view class="result-item" v-if="selectedDate">
<text class="result-label">单选日期</text>
<text class="result-value">{{ selectedDate }}</text>
</view>
<view class="result-item" v-if="selectedRange.start && selectedRange.end">
<text class="result-label">日期范围</text>
<text class="result-value">{{ selectedRange.start }} {{ selectedRange.end }}</text>
<text class="result-days">{{ rangeDays }}</text>
</view>
</view>
<!-- 日历组件 - 单选模式 -->
<Calendar
:visible="calendarVisible"
:price-data="priceData"
mode="single"
:default-value="selectedDate"
@close="handleCalendarClose"
@select="handleDateSelect"
/>
<!-- 日历组件 - 范围选择模式 -->
<Calendar
:visible="rangeCalendarVisible"
:price-data="priceData"
mode="range"
:default-value="[selectedRange.start, selectedRange.end]"
@close="handleRangeCalendarClose"
@range-select="handleRangeSelect"
/>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import Calendar from './index.vue'
// 响应式数据
const calendarVisible = ref(false)
const rangeCalendarVisible = ref(false)
const selectedDate = ref('')
const selectedRange = ref({
start: '',
end: ''
})
// 模拟价格数据
const priceData = ref({
'2024-01-15': 299,
'2024-01-16': 399,
'2024-01-17': 199,
'2024-01-18': 299,
'2024-01-19': 399,
'2024-01-20': 499,
'2024-01-21': 599,
'2024-01-22': 299,
'2024-01-23': 199,
'2024-01-24': 299,
'2024-01-25': 399,
'2024-01-26': 299,
'2024-01-27': 199,
'2024-01-28': 299
})
// 计算属性
const rangeDays = computed(() => {
if (!selectedRange.value.start || !selectedRange.value.end) return 0
const start = new Date(selectedRange.value.start)
const end = new Date(selectedRange.value.end)
const diffTime = Math.abs(end - start)
return Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1
})
// 方法定义
// 打开单选日历
const openCalendar = () => {
calendarVisible.value = true
}
// 打开范围选择日历
const openRangeCalendar = () => {
rangeCalendarVisible.value = true
}
// 处理单选日历关闭
const handleCalendarClose = () => {
calendarVisible.value = false
}
// 处理范围选择日历关闭
const handleRangeCalendarClose = () => {
rangeCalendarVisible.value = false
}
// 处理日期选择
const handleDateSelect = (data) => {
selectedDate.value = data.date
calendarVisible.value = false
console.log('选择的日期:', data)
}
// 处理范围选择
const handleRangeSelect = (data) => {
selectedRange.value = {
start: data.startDate,
end: data.endDate
}
rangeCalendarVisible.value = false
console.log('选择的日期范围:', data)
}
</script>
<style lang="scss" scoped>
.calendar-example {
padding: 20px;
background-color: #f5f5f5;
min-height: 100vh;
}
.page-header {
margin-bottom: 30px;
text-align: center;
}
.page-title {
font-size: 24px;
font-weight: 600;
color: #262626;
}
.trigger-section {
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 30px;
}
.date-input {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
background-color: #ffffff;
border-radius: 8px;
border: 1px solid #d9d9d9;
transition: border-color 0.2s;
&:active {
border-color: #1890ff;
}
}
.input-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
}
.input-label {
font-size: 14px;
color: #8c8c8c;
font-weight: 500;
}
.input-value {
font-size: 16px;
color: #262626;
font-weight: 500;
}
.input-placeholder {
font-size: 16px;
color: #bfbfbf;
}
.result-section {
padding: 20px;
background-color: #ffffff;
border-radius: 8px;
margin-bottom: 20px;
}
.result-title {
font-size: 16px;
font-weight: 600;
color: #262626;
margin-bottom: 12px;
}
.result-item {
display: flex;
align-items: center;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
.result-label {
font-size: 14px;
color: #8c8c8c;
margin-right: 8px;
min-width: 80px;
}
.result-value {
font-size: 14px;
color: #1890ff;
font-weight: 500;
}
.result-days {
font-size: 12px;
color: #52c41a;
margin-left: 8px;
}
</style>