一、前言
别人的东西用起来总是那么的不顺手,UI库的日历组件竟然不返回星期几,完全无法忍受,于是自己动手写了一个日历组件。
自己写的东西,那就是想怎么搞就怎么搞,哈哈哈哈哈。
二、代码
我使用的navie的按钮和tailwind的css,替换起来很方便的。
<template>
<div class="w-full p-2">
<h1 class="w-full flex justify-between items-center my-2 px-3 h-10 ">
<span class="text-2xl leading-10 font-semibold">{{ nian + " " + hanziyue + "月" }}</span>
<n-button-group>
<n-button @click="gaimonth(-1)" round>
<span>{{"<"}}</span>
<span>{{"<"}}</span>
<span>上个月</span>
</n-button>
<n-button @click="gaimonth(1)" round>
<span>下个月</span>
<span>{{">"}}</span>
<span>{{">"}}</span>
</n-button>
</n-button-group>
<n-button @click="getnianyueri()" type="primary">回到今天</n-button>
</h1>
<div class="w-full flex flex-wrap justify-start items-start">
<div class="w-1/7 min-w-32 h-32 border border-gray-300 cursor-pointer" v-for="item in daylist" :key="item.timestamp" :class="item.month!==yue?'text-gray-400':''" @click="clickevent(item)">
<div class="w-full h-5 flex justify-between items-center p-1">
<span>{{item.day}}</span>
<span v-if="item.day===xianzaitime.ri && item.month===xianzaitime.yue && item.year===xianzaitime.nian" class="text-blue-600">今天</span>
<span>{{item.zhou}}</span>
</div>
<slot :year="item.year" :month="item.month" :day="item.day" :week="item.week"></slot>
</div>
</div>
</div>
</template>
<script setup>
import {computed, ref,defineEmits} from "vue";
import {useStore} from "vuex"
import {useRoute, useRouter} from "vue-router"
import numtozh from "../../util/numtozh";
import weektozh from "../../util/weektozh";
import {NButton,NButtonGroup} from "naive-ui"
const store = useStore()
const router = useRouter()
const route = useRoute()
const emit = defineEmits(["handleclick","changemonth"])
// 需要展示的所有日期列表
const daylist = ref([])
// 年月日数据暂存
const shijian = ref(null)
const nian = ref(null)
const yue = ref(null)
const ri = ref(null)
const getnianyueri = (canshu = null) => {
// 置空日期列表
daylist.value = []
if (canshu) {
shijian.value = new Date(canshu)
} else {
shijian.value = new Date();
}
nian.value = shijian.value.getFullYear()
yue.value = shijian.value.getMonth() + 1
ri.value = shijian.value.getDate()
// 当前显示月份改变后,需要向父组件抛出,父组件可以根据月份更新日程
emit("changemonth",{year:nian.value,month:yue.value})
tianchong()
}
// 计算需要展示的第一个日期
const startandendday=()=>{
const cloneNowDate = new Date(shijian.value);
// 先获取这个月的第一天
const firstdaytime = cloneNowDate.setDate(1)
// 获取第一天是周几 ,修改2021年7月26日 14:42:58,周日是0不是7,我草。
let firstdayweek = new Date(firstdaytime).getDay()
if(firstdayweek===0){
firstdayweek=7
}
// 展示时间的第一天
return firstdaytime - (firstdayweek - 1) * 24 * 60 * 60 * 1000
}
// 向列表填充数据
const tianchong=()=>{
const starttime = startandendday()
console.log(starttime,"开始时间")
for (let i=0;i<=60;i++){
let shuju = {}
const shijianchuo = starttime + i*24*60*60*1000
const sj = new Date(shijianchuo)
const nian1 = sj.getFullYear()
const yue1 = sj.getMonth() +1
const ri1 = sj.getDate()
const week = sj.getDay()
if(yue.value===1){
if(yue1>yue.value && yue1 !== 12){
if(week===1 || week ===7){break}
}
}else if(yue.value===12){
if(yue1-yue.value===-11){
if(week===1 || week ===7){break}
}
}else{
if(yue1>yue.value){
if(week===1 || week ===7){break}
}
}
shuju["timestamp"] = shijianchuo
shuju["year"] = nian1
shuju["month"] = yue1
shuju["day"] = ri1
shuju["week"] = week
shuju["zhou"] = weektozh(week)
daylist.value.push(shuju)
}
}
// 日期点击事件
const clickevent=(item)=>{
emit("handleclick",item)
// 如果点击的日期不是当前月的,修改当前时间
if(item.month !== yue.value){
getnianyueri(item.timestamp)
}
}
// 数字转汉字
const hanziyue = computed(()=>{
return numtozh(yue.value)
})
// 点击上个月或者下个月
const gaimonth=(num)=>{
let newmonth = yue.value + num
// 如果大于12,转到下一年
if(newmonth>12){
nian.value += 1
newmonth = 1
}
const sj = new Date(Date.parse(nian.value+"/"+newmonth+"/"+ri.value)).getTime()
getnianyueri(sj)
}
// 获取今天的时间
const xianzaitime = ref({})
const getnow = ()=>{
const sj = new Date()
xianzaitime.value["nian"] = sj.getFullYear()
xianzaitime.value["yue"] = sj.getMonth() +1
xianzaitime.value["ri"] = sj.getDate()
}
// 初始化区域
getnow()
getnianyueri()
</script>
<style scoped>
</style>
引入的两个方法的代码
/*
* 数字转汉字,就是顶部显示的月份,数字不好看,换成汉字
* */
const dict = {
0: "零",
1: "壹",
2: "贰",
3: "弎",
4: "肆",
5: "伍",
6: "陆",
7: "柒",
8: "捌",
9: "玖",
10: "拾",
11: "拾壹",
12: "拾贰",
}
export default function (num){
return dict[num];
}
/*
* 数字转汉字,就是每个日期右上角显示的周几
* */
const dict2 = {
1:"周一",
2:"周二",
3:"周三",
4:"周四",
5:"周五",
6:"周六",
0:"周日",
}
export default function (num){
return dict2[num]
}
三、使用方法
<rili @handleclick="showtime" @changemonth=“getdata”>
<template v-slot="yuansu">
<div class="w-full h-full px-2 mt-1 overflow-x-hidden overflow-y-auto">
<span>{{yuansu.year}}-{{yuansu.month}}-{{yuansu.day}}</span>
<p>自定义内容</p>
</div>
</template>
</rili>
四、效果图
五、结束
有问题或者意见可以提。