当前位置: 首页 > news >正文

vue3 自定义vant-calendar header/footer/maincontent

vue3 自定义vant-calendar header/footer/maincontent
参考代码如下
在这里插入图片描述

vue

<template><van-calendar:min-date="minDate":max-date="maxDate"class="daily-sign-in-calendar"confirm-text="关闭"title="":show-confirm="true":show="show"switch-mode="month":formatter="formatter"@confirm="confirmAction"@close="confirmAction":default-date="currentDate"style="height:85%;max-height:568px"><template #title><div class="custom-title-container"><div class="title-header"><span>签到日历</span></div><div class="title-content"><div class="month-switch"><van-iconname="arrow-left"@click="switchMonth(-1)"class="arrow-btn"/><span class="current-month">{{ currentYear }}年{{ currentMonth }}月</span><van-iconname="arrow"@click="switchMonth(+1)"class="arrow-btn"/></div><div class="sign-card-info"><span>补签卡 {{ signCardCount }} 张</span></div></div></div></template><template v-slot:text=day><div class="date-main"><div v-if="day.className&&day.className.includes('add-signed-tick')"><img class="signed-tick-icon" :src="SIGNED_TICK" alt="icon" /><!-- <img class="unsigned-block-icon" :src="UNSIGNED_BLOCK" alt="icon" /> --></div><div v-else-if="day.className&&day.className.includes('add-signed-gift')"><img class="signed-gift-icon" :src="SIGNED_GIFT" alt="icon" /></div><div v-else-if="day.className&&day.className.includes('add-retroactive-sign')"><img class="retroactive-sign-icon" :src="RETROACTIVE_SIGN" alt="icon" /></div><div v-else><img class="unsigned_block-icon" :src="UNSIGNED_BLOCK" alt="icon" /></div></div></template><template v-slot:bottom-info=day><div class="date-bottom"><div v-if="day.className&&day.className.includes('calendar-today')" class="calendar-today-test">今</div><div v-else>{{day.date.getDate()}}</div></div></template><template #footer><div class="max-retroactive">最多补签3次</div><div class="split-line"></div><div class="calendar-close"><van-button class="calendar-close-btn" type="default">关闭</van-button></div></template></van-calendar>
</template><script setup>
// import { ref } from 'vue';
import { ref, computed, onMounted } from 'vue';
import { useLess } from '@/models/hooks';
import zhCN from 'vant/es/locale/lang/zh-CN';
import imageLink from '@/configs/imageLink';
const { UNSIGNED_CROSS, RETROACTIVE_SIGN, SIGNED_GIFT, SIGNED_TICK, UNSIGNED_BLOCK } = imageLink;
// 创建本地副本避免影响全局配置
const localLocale = { ...zhCN };
localLocale.vanCalendar.weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
useLess('components/Calendar.less');
defineProps({show: {type: Boolean,default: false}
});
const emit = defineEmits(['update:show']);// const customSubtitle = 123;const confirmAction = () => {emit('update:show', false);
};// 定义日期和对应的标识
const dateTime1 = [{ date1: '20250710', value1: true },{ date1: '20250711', value1: true },{ date1: '20250712', value2: true },{ date1: '20250713', value2: true },{ date1: '20250714', value3: true },{ date1: '20250715', value3: true },{ date1: '20250716', value1: true },{ date1: '20250717', value1: true },{ date1: '20250718', value4: true },{ date1: '20250719', value4: true },{ date1: '20250720', value5: true },
];// 格式化日历中的每一天
const formatter = (day) => {const year = day.date.getFullYear();const month = String(day.date.getMonth() + 1).padStart(2, '0'); // 确保月份是两位数const date = String(day.date.getDate()).padStart(2, '0'); // 确保日期是两位数const dateTime = `${year}${month}${date}`; // 格式化日期// 遍历日期数组,检查是否有匹配的日期dateTime1.forEach(item => {if (item.date1 === dateTime) {// 根据标识添加不同的类名if (item.value1) {day.className += " add-signed-tick";}if (item.value2) {day.className += " add-signed-gift";}if (item.value3) {day.className += " add-retroactive-sign";}if (item.value4) {day.className += " add-unsigned-block";}if (item.value5) {day.className += " add-unsigned-cross";}}});const todayTimestamp = new Date(new Date().toDateString()).getTime();const dayTimestamp = Date.parse(day.date);if (dayTimestamp === todayTimestamp) {day.className += " calendar-today";}return day; // 返回处理后的day对象
};// 日期范围控制
const currentDate = ref(new Date());
const minDate = ref(new Date('2025-01-01'));
const maxDate = ref(new Date('2025-12-31'));// 补签卡数量
const signCardCount = ref(0);// 计算当前年月
const currentYear = computed(() => currentDate.value.getFullYear());
const currentMonth = computed(() => currentDate.value.getMonth() + 1);const switchMonth = (n) => {const newDate = new Date(currentDate.value.getFullYear(),currentDate.value.getMonth() + n, // 核心:修改月份1 // 固定为1号,避免小月切换到大月时日期越界);// 边界检查:不超出min/max范围if (newDate >= minDate.value && newDate <= maxDate.value) {currentDate.value = newDate; // 修改状态,日历自动切换}console.log('aaaswitchMonth', currentDate);
};
const change = () => {const newDate = new Date(currentDate.value.getFullYear(),currentDate.value.getMonth() - 1, // 核心:修改月份1 // 固定为1号,避免小月切换到大月时日期越界);if (newDate >= minDate.value && newDate <= maxDate.value) {currentDate.value = newDate; // 修改状态,日历自动切换}
};
onMounted(() => {change();
});
</script>

less

@import '@/assets/styles/cn/common.less';.daily-sign-in-calendar{
.van-calendar__header-title{height: 196px;
}
.van-calendar__body{flex: none;background-color: #fff;
}
.custom-title-container {padding: 20px 20px;background-color: #fff;
}.title-header {height: 96px;text-align: center;margin-bottom: 16px;
}.title-header span {font-size: 36px; font-weight: bold;color: #333;
}.title-content {height: 38px;display: flex;justify-content: space-between;align-items: center;
}.month-switch {display: flex;align-items: center;
}.arrow-btn {font-size: 36px;color: #333;cursor: pointer;padding: 8px; 
}.current-month {margin: 0 36px; color: #0F1111;font:600 26px/38px PingFang SC;
}.sign-card-info {display: flex;align-items: center;color: #0F1111;font:600 26px/38px PingFang SC;
}.ticket-icon {margin-right: 8px; color: #ff7d00;
}.calendar-today-test {color: #EB1745;font-size: 22px; 
}.signed {color: #ee0a24;font-size: 28px;
}.van-calendar__day {height: 88px;margin-bottom: 40px;justify-content: space-between;flex-direction: column;
}
.van-calendar__selected-day{justify-content: space-between;flex-direction: column;
}
.van-calendar__weekdays{margin-bottom: 24px;.van-calendar__weekday {height: 38px; line-height: 38px; font-size: 26px;}
}.van-calendar__header-subtitle{display: none;
}
.van-calendar__month-mark{display: none;
}
.calendar-close-btn{width: 100%;height: 70px;border-color: #D9D9D9;background: #FAFAFA;border-radius: 99px;margin: 24px auto 0;box-shadow: 0px 2px 8px 0px #F0F2F280;
}
.van-calendar__selected-day{color:#0f1111;background: none;
}
.van-popup__close-icon--top-right{top:40px;right:40px
}
.van-calendar__footer{padding: 0 24px 40px;flex:1;
}
.max-retroactive{margin-left: 8px;margin-top: 24px;margin-bottom: 22px;
}
.split-line{width: calc(100% + 48px);margin-left: -24px;height: 2px;background-color: #F0F2F2;
}
}.date-main {width: 56px;height: 56px;display: flex;justify-content: center;
}
.date-bottom{display: flex;flex: 1;font:22px/30px 'PingFang SC';justify-content: center;
}
.signed-tick-icon{width: 56px;height: 56px;
}
.van-calendar__bottom-info{bottom:0;
}
http://www.dtcms.com/a/284883.html

相关文章:

  • 【实时Linux实战系列】利用容器化实现实时应用部署
  • 量化环节剖析
  • 鸿蒙Navigation跳转页面白屏
  • 【agent实战】基于 LangGraph 实现 Agentic RAG:原理、实战与创新全解
  • SII9022ACNU-富利威-HDMI芯片
  • stack,queue,priority_queue的模拟实现及常用接口
  • Qt6-学习Cmakelist(翻译官方文档)
  • Pytorch深度学习框架实战教程02:开发环境部署
  • python学智能算法(二十二)|SVM-点与超平面的距离
  • faster-lio仿真环境问题及解决
  • 腾讯云服务上下载docker以及使用Rabbitmq的流程
  • Python网络爬虫——介绍
  • 【unitrix】 6.5 基础整数类型特征(base_int.rs)
  • Redis:哨兵(Sentinel)
  • MySQL的索引操作及底层结构浅析
  • 产品经理如何描述用户故事
  • modelscope ProxyError: HTTPSConnectionPool(host=‘www.modelscope.cn‘, port=443)
  • 作物长势产量预测yyds!遥感数据同化DSSAT模型,区域精准农业就靠它!
  • 27、鸿蒙Harmony Next开发:ArkTS并发(Promise和async/await和多线程并发TaskPool和Worker的使用)
  • Hyperledger Fabric:构建企业区块链网络的实践指南
  • 【实时Linux实战系列】硬件中断与实时性
  • 什么是GEO 和 SEO ?GEO 与 SEO 有什么区别?如何快速入门GEO?
  • 解决宝塔面板SSL报错 - AttributeError: module ‘acme_v2‘ has no attribute ‘acme_v2‘
  • 搜广推校招面经九十四
  • 神经网络构建
  • STM32之土壤湿度传感器模块
  • Toward the unification of kselftests and KUnit
  • MYSQL-进阶-锁
  • 离散与组合数学 杂记
  • 电子制造企业排产优化实战:用JVS智能排产的排产策略实现交期100%可控