chat-app/src/components/x-calendar/index.vue
scout b54bfe63ad
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
init
2024-11-11 14:46:14 +08:00

156 lines
3.9 KiB
Vue

<script setup>
import {nextTick, ref,computed,watch} from "vue";
import dayjs from "dayjs";
import {useCalendar} from "@/store/calendar";
const {generateCalendarData}= useCalendar()
const current = ref(1);
const swiperItems = [0, 1, 2];
const showDays=(item)=>{
if (current.value===item){
return currentDays.value
}else{
if (current.value-item===1 ||
current.value - item === -2){
return preDays.value
}else{
return nextDays.value
}
}
}
const props=defineProps({
value:{
type:String,
default:''
}
})
const swiperHeight=()=>{
return `${showDays(current.value)?.length/7 * 72}rpx`
}
const emit = defineEmits(['update:value','change-dates']);
const currentDays = ref([])
const preDays = ref([])
const nextDays = ref([])
const nextMonth = computed(()=>{
return dayjs(props.value, 'YYYY-MM').add(1, 'month').format('YYYY-MM')
})
const preMonth = computed(()=>{
return dayjs(props.value, 'YYYY-MM').subtract(1, 'month').format('YYYY-MM')
})
const initDates=()=>{
currentDays.value=generateCalendarData(props.value)
preDays.value=generateCalendarData(preMonth.value)
nextDays.value=generateCalendarData(nextMonth.value)
emit('change-dates',showDays(current.value))
}
watch(()=>props.value,()=>{
initDates()
})
const initLoad=()=>{
initDates()
}
initLoad()
function updateMonthsData(direction) {
if (direction === "prev") {
emit('update:value',preMonth.value)
} else if (direction === "next") {
emit('update:value',nextMonth.value)
}
nextTick(()=>{
initDates()
})
}
function handleSwiperChange(e) {
const pre = current.value;
const current2 = e.detail.current;
/* 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周
*current - pre === 1, -2时是下一个月/周
*current -pre === -1, 2时是上一个月或者上一周
*/
current.value = current2;
if (current2 - pre === 1 || current2 - pre === -2) {
updateMonthsData('next');
} else {
updateMonthsData('prev');
}
}
const contract=ref(false)
</script>
<template>
<div class="x-calendar">
<div class="content1">
<div class="wrap1" v-for="day in ['日', '一', '二', '三', '四', '五', '六']" :key="day">
{{ day }}
</div>
</div>
<div class="content4"></div>
<div class="content2"></div>
<swiper :duration="500" :current="current" :style="{height: contract?'72rpx':swiperHeight(),transition: `height 0.2s ease`}" :indicator-dots="false" :circular="true" @change="handleSwiperChange">
<swiper-item v-for="(item, index) in swiperItems" :key="item">
<div class="content3">
<div class="wrap1" v-for="(day,index1) in showDays(item)" :key="day.date">
<slot name="cell" :data="day" :index="index1" ></slot>
</div>
</div>
</swiper-item>
</swiper>
<div class="content5" @click="contract=!contract">
<div :class="`triangle ${contract?'rotate':''}`"></div>
</div>
</div>
</template>
<style scoped lang="scss">
.x-calendar {
.content5{
padding-top: 22rpx;
padding-bottom: 22rpx;
display: flex;
justify-content: center;
align-items: center;
.triangle {
width: 0;
height: 0;
border-left: 14rpx solid transparent;
border-right: 14rpx solid transparent;
border-bottom: 12rpx solid #C2C2C2;
&.rotate{
transform: rotate(180deg);
}
}
}
.content4{
margin-top: 32rpx;
width: 100%;
height: 1rpx;
background-color: #EFEFF5;
margin-bottom: 24rpx;
}
.content3 {
display: flex;
flex-wrap: wrap;
.wrap1 {
flex: 1 0 calc(100% / 7);
}
}
.content1 {
margin-top: 46rpx;
display: flex;
.wrap1 {
font-size: 28rpx;
color: #191919;
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
}
.content2 {
height: 4rpx;
}
}
</style>