您的位置:首页 > 游戏 > 手游 > vue3 手写日历组件

vue3 手写日历组件

2024/12/28 1:56:06 来源:https://blog.csdn.net/qq_42095701/article/details/140914498  浏览:    关键词:vue3 手写日历组件

找了很久vue3的element样式一直没办法修改实现。只能手写日历了。借鉴了一些大佬的代码

调用:

再要使用的地方引入

import calendarelement from './calendarelement.vue'  //日历组件
 <div >     <calendarelement />  //日历</div>

效果:

<template><div class="plan-zone"><div class="btn-group"><div class="left-btn"><el-button-group><el-button @click="prevMonth" type="primary">上一个月</el-button>          <el-button type="primary" @click="goToCurrentDay">回到今天</el-button><el-button @click="nextMonth" type="primary">下一个月</el-button></el-button-group></div><div class="right-btn"><button class="new">长箱</button><button class="ing">短箱</button><button class="finish">双箱</button></div></div><table class="parent-table"><thead><th>周一</th><th>周二</th><th>周三</th><th>周四</th><th>周五</th><th>周六</th><th>周日</th></thead><tbody><tr v-for="(week, windex) in weeks" :key="windex"><td v-for="(day, dindex) in week" :class="{ highlight: isToday(day.date) }" :key="dindex"><div class="content":class="{faded: !isCurrentMonth(day.date),hovered: isHovered(day.date),selected: isSelected(day.date)}"@mouseenter="hoveredDay = day.date"@mouseleave="hoveredDay = null"@click="selectDay(day.date)"><div class="top-day">{{ day.date.getDate() }}日  </div><div class="middle-event"><div><span style="color: #409eef;">长箱</span>:<span>123</span></div></div><div class="bottom-event"><div><span style="color: #ff974a;">短箱</span>:<span>123</span></div></div><div class="bottom-event"><div><span style="color: #3dd599;">双箱</span>:<span>123</span></div></div></div> </td></tr></tbody></table></div>
</template><script setup>
import { ref, computed } from 'vue';const current = ref(new Date());
const today = ref(new Date());const getCurDate = () => {const date = new Date();const year = date.getFullYear();let month = date.getMonth() + 1;if (month < 10) {month = "0" + month;}return `${year}-${month}`;
};const isToday = (date) => {const todayDate = new Date();return (date.getDate() === todayDate.getDate() &&date.getMonth() === todayDate.getMonth() &&date.getFullYear() === todayDate.getFullYear());
};const goToCurrentDay = () => {current.value = new Date(today.value);
};const isCurrentMonth = (date) => {return date.getMonth() === current.value.getMonth();
};const prevMonth = () => {current.value.setMonth(current.value.getMonth() - 1);current.value = new Date(current.value);
};const nextMonth = () => {current.value.setMonth(current.value.getMonth() + 1);current.value = new Date(current.value);
};const hoveredDay = ref(null);
const selectedDay = ref(null);const isHovered = (date) => hoveredDay.value && hoveredDay.value.getTime() === date.getTime();
const isSelected = (date) => selectedDay.value && selectedDay.value.getTime() === date.getTime();
const selectDay = (date) => selectedDay.value = date;const getMonthData = (year, month) => {const weeks = [];const firstDay = new Date(year, month - 1, 1);const lastDayOfCurrentMonth = new Date(year, month, 0);const lastDayOfPrevMonth = new Date(year, month - 1, 0);let startDayOfWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay();let dayCount = 1;let prevMonthDayCount = lastDayOfPrevMonth.getDate() - startDayOfWeek + 2;for (let i = 0; i < 6; i++) {const week = [];for (let j = 0; j < 7; j++) {if (i === 0 && j < startDayOfWeek - 1) {week.push({ date: new Date(year, month - 2, prevMonthDayCount++) });} else if (dayCount > lastDayOfCurrentMonth.getDate()) {week.push({date: new Date(year, month, dayCount++ - lastDayOfCurrentMonth.getDate()),});} else {week.push({ date: new Date(year, month - 1, dayCount++) });}}weeks.push(week);}return weeks;
};const weeks = computed(() => getMonthData(current.value.getFullYear(), current.value.getMonth() + 1));</script><style lang="scss" scoped>
.faded {opacity: 0.3;
}
.highlight {background: rgba(255, 220, 40, 0.15);
}
.plan-zone {margin-top: 10px;.btn-group {display: flex;justify-content: space-between;.right-btn {button.new {background-color: #fff;border: 1px solid #fff;color: #409eef;position: relative;&::before {content: "";width: 8px;height: 8px;border-radius: 50%;position: absolute;top: 7px;left: -3px;background-color: #409eef;}}button.ing {background-color: #fff;border: 1px solid #fff;color: #ff974a;position: relative;&::before {content: "";width: 8px;height: 8px;border-radius: 50%;position: absolute;top: 7px;left: -3px;background-color: #ff974a;}}button.finish {background-color: #fff;border: 1px solid #fff;color: #3dd599;position: relative;&::before {content: "";width: 8px;height: 8px;border-radius: 50%;position: absolute;top: 7px;left: -3px;background-color: #3dd599;}}}}
}
.parent-table {border-collapse: collapse;table-layout: fixed;width: 100%;margin-top: 20px;th,td {width: 14.4%;border: 1px solid #ddd;}td {padding: 2px 3px;.content {position: relative;min-height: 80px;transition: background-color 0.3s ease;}vertical-align: top;.top-day {text-align: right;font-size: 16px;}}
}
.table-date {display: flex;> div {flex: 1;}
}
.hovered {background-color: rgba(64, 56, 180, 0.1);
}
.selected {background-color: rgba(70, 168, 40, 0.2);
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com