用vue做了一个垂直无限滑动日历,在这里记录一下实现(●’◡’●)

效果

组件

verticalCalendar.vue

<template><div ref="container" class="calendar-vt"><div class="top-month">{{ currentMonth }}月</div><ul ref="scroll" class="scroll" @scroll="fnScroll"><template v-for="(item, index) in dateList"><li v-if="item.type === 'month'" :key="index" class="li-month">{{ item.num }}月</li><liv-else:key="index"class="li-day":class="liDayClass(item.date)"@click="selectDate(item.date)"><span class="date">{{ item.num }}</span><span class="lunar">{{ item.date | getLunarDate }}</span></li></template></ul></div>
</template>
<script>
import calendar from "@/utils/calendar";
import { throttle } from "throttle-debounce";
import { formatDate } from "@/utils/moment.js";
export default {name: "vertical-calendar",props: {currentDate: {type: Date,default: () => new Date(),},},data() {return {dateList: [], // 日历列表cellCount: 0, // 日历个数fnScroll: () => {},currentMonth: 0,value: new Date(), // 当前日历显示的中间日期};},computed: {liDayClass() {return (date) => {if (formatDate(this.currentDate, "YYYY-MM-DD") ==formatDate(date, "YYYY-MM-DD")) {return ["li-day", "isToday"];} else {return "li-day";}};},},filters: {// 农历getLunarDate(date) {let year = date.getFullYear();let month = date.getMonth() + 1;let day = date.getDate();let lunarCalendar = calendar.solar2lunar(year, month, day);if (lunarCalendar.festival) return lunarCalendar.festival;if (lunarCalendar.lunarFestival) return lunarCalendar.lunarFestival;return lunarCalendar.IDayCn;},},created() {this.fnScroll = throttle(500, this.handleScroll);},mounted() {this.value = this.currentDate;this.$nextTick(() => {let height = this.$refs.container.offsetHeight;this.cellCount = Math.floor(height / 50);// 获取当年日历,从上一年的12-31至下一年1-1,防止滚动不到最顶或最底this.dateList = calendar.getFullYearDate(this.currentDate,this.cellCount);// 计算当前日期的位置let index = this.dateList.findIndex((item) => {if (item.type === "day") {return (formatDate(this.currentDate, "YYYY-MM-DD") ==formatDate(item.date, "YYYY-MM-DD"));} else return false;});setTimeout(() => {// 滚动到当前日期位置this.$refs.scroll.scrollTop = (index - this.cellCount / 2) * 50;this.currentMonth = this.dateList[index].date.getMonth() + 1;});});},methods: {handleScroll(e) {// 日历触顶,计算上一年日历if (e.target.scrollTop === 0) {this.value = new Date(this.value.getFullYear() - 1 + "/12/31");this.dateList = calendar.getFullYearDate(this.value, this.cellCount);this.$nextTick(() => {// 滚动到上一年最底部e.target.scrollTop = 365 * 50;this.currentMonth = 12;});} else if (Math.ceil(e.target.scrollTop) ==e.target.scrollHeight - e.target.clientHeight) {// 日历触底,计算下一年日历this.value = new Date(this.value.getFullYear() + 1 + "/1/1");this.dateList = calendar.getFullYearDate(this.value, this.cellCount);this.$nextTick(() => {// 滚动到下一年最顶部e.target.scrollTop = 5;this.currentMonth = 1;});} else {// 更新当前显示第一个日期所属月份let index = Math.ceil(e.target.scrollTop / 50);if (this.dateList[index].type === "month") index++;this.currentMonth = this.dateList[index].date.getMonth() + 1;}},selectDate(date) {this.$emit("on-select", date);},},
};
</script>
<style lang="scss" scoped>
.calendar-vt {width: 60px;height: 100%;position: relative;.top-month {height: 50px;display: flex;justify-content: center;align-items: center;flex-direction: column;border: 1px solid #ccc;cursor: pointer;background-color: #0474c7;color: #fff;font-size: 18px;}.scroll {height: calc(100% - 50px);overflow-y: auto;scrollbar-width: none; /* Firefox */-ms-overflow-style: none; /* IE 10+ */&::-webkit-scrollbar {display: none;}.li-month,.li-day {height: 50px;display: flex;justify-content: center;align-items: center;flex-direction: column;border: 1px solid #ccc;cursor: pointer;}.li-month {background-color: #0474c7;color: #fff;font-size: 18px;}.li-day {.date {font-size: 14px;}.lunar {font-size: 10px;color: #999;}}.isToday {background-color: #50a3e6;.date,.lunar {color: #fff;}}}
}
</style>

工具类

calendar.js

/**
* @1900-2100区间内的公历、农历互转
* @charset UTF-8
* @Author  Jea杨(JJonline@JJonline.Cn)
* @Time    2014-7-21
* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time    2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
const calendar = {/*** 农历1900-2100的润大小信息表* @Array Of Property* @return Hex*/lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,//1900-19090x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,//1910-19190x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,//1920-19290x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,//1930-19390x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,//1940-19490x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,//1950-19590x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,//1960-19690x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,//1970-19790x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,//1980-19890x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0,//1990-19990x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,//2000-20090x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,//2010-20190x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,//2020-20290x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,//2030-20390x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,//2040-2049/**Add By JJonline@JJonline.Cn**/0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0,//2050-20590x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4,//2060-20690x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0,//2070-20790x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160,//2080-20890x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252,//2090-20990x0d520],//2100/*** 公历每个月份的天数普通表* @Array Of Property* @return Number*/solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],/*** 天干地支之天干速查表* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]* @return Cn string*/Gan: ["\u7532", "\u4e59", "\u4e19", "\u4e01", "\u620a", "\u5df1", "\u5e9a", "\u8f9b", "\u58ec", "\u7678"],/*** 天干地支之地支速查表* @Array Of Property* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]* @return Cn string*/Zhi: ["\u5b50", "\u4e11", "\u5bc5", "\u536f", "\u8fb0", "\u5df3", "\u5348", "\u672a", "\u7533", "\u9149", "\u620c", "\u4ea5"],/*** 天干地支之地支速查表<=>生肖* @Array Of Property* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]* @return Cn string*/Animals: ["\u9f20", "\u725b", "\u864e", "\u5154", "\u9f99", "\u86c7", "\u9a6c", "\u7f8a", "\u7334", "\u9e21", "\u72d7", "\u732a"],/*** 阳历节日*/festival: {'1-1': { title: '元旦' },'5-1': { title: '劳动节' },'5-4': { title: '青年节' },'6-1': { title: '儿童节' },'9-10': { title: '教师节' },'10-1': { title: '国庆节' },'12-25': { title: '圣诞节' },},/*** 农历节日*/lfestival: {'12-30': { title: '除夕' },'1-1': { title: '春节' },'1-15': { title: '元宵节' },'5-5': { title: '端午节' },'8-15': { title: '中秋节' },},/*** 返回默认定义的阳历节日*/getFestival() {return this.festival},/*** 返回默认定义的内容里节日*/getLunarFestival() {return this.lfestival},/**** @param {Object} 按照festival的格式输入数据,设置阳历节日*/setFestival(param = {}) {this.festival = param},/**** @param {Object} 按照lfestival的格式输入数据,设置农历节日*/setLunarFestival(param = {}) {this.lfestival = param},/*** 24节气速查表* @Array Of Property* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]* @return Cn string*/solarTerm: ["\u5c0f\u5bd2", "\u5927\u5bd2", "\u7acb\u6625", "\u96e8\u6c34", "\u60ca\u86f0", "\u6625\u5206", "\u6e05\u660e", "\u8c37\u96e8", "\u7acb\u590f", "\u5c0f\u6ee1", "\u8292\u79cd", "\u590f\u81f3", "\u5c0f\u6691", "\u5927\u6691", "\u7acb\u79cb", "\u5904\u6691", "\u767d\u9732", "\u79cb\u5206", "\u5bd2\u9732", "\u971c\u964d", "\u7acb\u51ac", "\u5c0f\u96ea", "\u5927\u96ea", "\u51ac\u81f3"],/*** 1900-2100各年的24节气日期速查表* @Array Of Property* @return 0x string For splice*/sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f','97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e','97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e','97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721','7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721','7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd','7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721','7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35','7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],/*** 数字转中文速查表* @Array Of Property* @trans ['日','一','二','三','四','五','六','七','八','九','十']* @return Cn string*/nStr1: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341"],/*** 日期转农历称呼速查表* @Array Of Property* @trans ['初','十','廿','卅']* @return Cn string*/nStr2: ["\u521d", "\u5341", "\u5eff", "\u5345"],/*** 月份转农历称呼速查表* @Array Of Property* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']* @return Cn string*/nStr3: ["\u6b63", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u51ac", "\u814a"],/*** 返回农历y年一整年的总天数* @param lunar Year* @return Number* @eg:var count = calendar.lYearDays(1987) ;//count=387*/lYearDays: function (y) {var i, sum = 348;for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0; }return (sum + this.leapDays(y));},/*** 返回农历y年闰月是哪个月;若y年没有闰月 则返回0* @param lunar Year* @return Number (0-12)* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6*/leapMonth: function (y) { //闰字编码 \u95f0return (this.lunarInfo[y - 1900] & 0xf);},/*** 返回农历y年闰月的天数 若该年没有闰月则返回0* @param lunar Year* @return Number (0、29、30)* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29*/leapDays: function (y) {if (this.leapMonth(y)) {return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29);}return (0);},/*** 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法* @param lunar Year* @return Number (-1、29、30)* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29*/monthDays: function (y, m) {if (m > 12 || m < 1) { return -1 }//月份参数从1至12,参数错误返回-1return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);},/*** 返回公历(!)y年m月的天数* @param solar Year* @return Number (-1、28、29、30、31)* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30*/solarDays: function (y, m) {if (m > 12 || m < 1) { return -1 } //若参数错误 返回-1var ms = m - 1;if (ms == 1) { //2月份的闰平规律测算后确认返回28或29return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28);} else {return (this.solarMonth[ms]);}},/*** 农历年份转换为干支纪年* @param  lYear 农历年的年份数* @return Cn string*/toGanZhiYear: function (lYear) {var ganKey = (lYear - 3) % 10;var zhiKey = (lYear - 3) % 12;if (ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干if (zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1];},/*** 公历月、日判断所属星座* @param  cMonth [description]* @param  cDay [description]* @return Cn string*/toAstro: function (cMonth, cDay) {var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + "\u5ea7";//座},/*** 传入offset偏移量返回干支* @param offset 相对甲子的偏移量* @return Cn string*/toGanZhi: function (offset) {return this.Gan[offset % 10] + this.Zhi[offset % 12];},/*** 传入公历(!)y年获得该年第n个节气的公历日期* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起* @return day Number* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春*/getTerm: function (y, n) {if (y < 1900 || y > 2100) { return -1; }if (n < 1 || n > 24) { return -1; }var _table = this.sTermInfo[y - 1900];var _info = [parseInt('0x' + _table.substr(0, 5)).toString(),parseInt('0x' + _table.substr(5, 5)).toString(),parseInt('0x' + _table.substr(10, 5)).toString(),parseInt('0x' + _table.substr(15, 5)).toString(),parseInt('0x' + _table.substr(20, 5)).toString(),parseInt('0x' + _table.substr(25, 5)).toString()];var _calday = [_info[0].substr(0, 1),_info[0].substr(1, 2),_info[0].substr(3, 1),_info[0].substr(4, 2),_info[1].substr(0, 1),_info[1].substr(1, 2),_info[1].substr(3, 1),_info[1].substr(4, 2),_info[2].substr(0, 1),_info[2].substr(1, 2),_info[2].substr(3, 1),_info[2].substr(4, 2),_info[3].substr(0, 1),_info[3].substr(1, 2),_info[3].substr(3, 1),_info[3].substr(4, 2),_info[4].substr(0, 1),_info[4].substr(1, 2),_info[4].substr(3, 1),_info[4].substr(4, 2),_info[5].substr(0, 1),_info[5].substr(1, 2),_info[5].substr(3, 1),_info[5].substr(4, 2),];return parseInt(_calday[n - 1]);},/*** 传入农历数字月份返回汉语通俗表示法* @param lunar month* @return Cn string* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'*/toChinaMonth: function (m) { // 月 => \u6708if (m > 12 || m < 1) { return -1 } //若参数错误 返回-1var s = this.nStr3[m - 1];s += "\u6708";//加上月字return s;},/*** 传入农历日期数字返回汉字表示法* @param lunar day* @return Cn string* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'*/toChinaDay: function (d) { //日 => \u65e5var s;switch (d) {case 10:s = '\u521d\u5341'; break;case 20:s = '\u4e8c\u5341'; break;break;case 30:s = '\u4e09\u5341'; break;break;default:s = this.nStr2[Math.floor(d / 10)];s += this.nStr1[d % 10];}return (s);},/*** 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”* @param y year* @return Cn string* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'*/getAnimal: function (y) {return this.Animals[(y - 4) % 12]},/*** @param {String} date * @returns {Boolean} */isSolarPublicHoliday: function (date) {// 阳历:元旦、劳动节、国庆let solarArr = ["1-1", "1-2", "1-3", "5-1", "10-1", "10-2", "10-3"];return solarArr.indexOf(date) != -1;},isLunarPublicHoliday: function (date) {// 阴历:春节、清明、端午节、中秋节let lunarArr = ["1-1", "1-2", "1-3", "2-23", "5-5", "8-15"];return lunarArr.indexOf(date) != -1;},isFestival(slotDate, slotData) {// slotDate是标准时间// slotData是对象let solarDayArr = slotData.day.split("-");let lunarDay = calendar.solar2lunar(solarDayArr[0],solarDayArr[1],solarDayArr[2]);// 公历节日\农历节日\农历节气let festAndTerm = [];festAndTerm.push(lunarDay.festival == null ? "" : " " + lunarDay.festival);festAndTerm.push(lunarDay.lunarFestival == null ? "" : "" + lunarDay.lunarFestival);festAndTerm.push(lunarDay.Term == null ? "" : "" + lunarDay.Term);festAndTerm = festAndTerm.join("");// 原本的方法,return出的是一个Boolean// 更改过后返回Object:公立日期、农历日期return {solarDate: lunarDay.date,lunarDate: lunarDay.lunarDate};},/*** 传入阳历年月日获得详细的公历、农历object信息 <=>JSON* @param y  solar year* @param m  solar month* @param d  solar day* @return JSON object* @eg:console.log(calendar.solar2lunar(1987,11,01));*/solar2lunar: function (y, m, d) { //参数区间1900.1.31~2100.12.31y = parseInt(y)m = parseInt(m)d = parseInt(d)//年份限定、上限if (y < 1900 || y > 2100) {return -1;// undefined转换为数字变为NaN}//公历传参最下限if (y == 1900 && m == 1 && d < 31) {return -1;}//未传参  获得当天if (!y) {var objDate = new Date();} else {var objDate = new Date(y, parseInt(m) - 1, d)}var i, leap = 0, temp = 0;//修正ymd参数var y = objDate.getFullYear(),m = objDate.getMonth() + 1,d = objDate.getDate();var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000;for (i = 1900; i < 2101 && offset > 0; i++) {temp = this.lYearDays(i);offset -= temp;}if (offset < 0) {offset += temp; i--;}//是否今天var isTodayObj = new Date(),isToday = false;if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {isToday = true;}//星期几var nWeek = objDate.getDay(),cWeek = this.nStr1[nWeek];//数字表示周几顺应天朝周一开始的惯例if (nWeek == 0) {nWeek = 7;}//农历年var year = i;var leap = this.leapMonth(i); //闰哪个月var isLeap = false;//效验闰月for (i = 1; i < 13 && offset > 0; i++) {//闰月if (leap > 0 && i == (leap + 1) && isLeap == false) {--i;isLeap = true; temp = this.leapDays(year); //计算农历闰月天数}else {temp = this.monthDays(year, i);//计算农历普通月天数}//解除闰月if (isLeap == true && i == (leap + 1)) { isLeap = false; }offset -= temp;}// 闰月导致数组下标重叠取反if (offset == 0 && leap > 0 && i == leap + 1) {if (isLeap) {isLeap = false;} else {isLeap = true; --i;}}if (offset < 0) {offset += temp; --i;}//农历月var month = i;//农历日var day = offset + 1;//天干地支处理var sm = m - 1;var gzY = this.toGanZhiYear(year);// 当月的两个节气// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`var firstNode = this.getTerm(y, (m * 2 - 1));//返回当月「节」为几日开始var secondNode = this.getTerm(y, (m * 2));//返回当月「节」为几日开始// 依据12节气修正干支月var gzM = this.toGanZhi((y - 1900) * 12 + m + 11);if (d >= firstNode) {gzM = this.toGanZhi((y - 1900) * 12 + m + 12);}//传入的日期的节气与否var isTerm = false;var Term = null;if (firstNode == d) {isTerm = true;Term = this.solarTerm[m * 2 - 2];}if (secondNode == d) {isTerm = true;Term = this.solarTerm[m * 2 - 1];}//日柱 当月一日与 1900/1/1 相差天数var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10;var gzD = this.toGanZhi(dayCyclical + d - 1);//该日期所属的星座var astro = this.toAstro(m, d);var solarDate = y + '-' + m + '-' + dvar lunarDate = year + '-' + month + '-' + dayvar festival = this.festivalvar lfestival = this.lfestivalvar festivalDate = m + '-' + dvar lunarFestivalDate = month + '-' + dayvar monthDay = this.monthDays(year, month);return {date: solarDate,lunarDate: lunarDate,festival: festival[festivalDate] ? festival[festivalDate].title : null,lunarFestival: lunarFestivalDate == '12-29' && monthDay == 29 ? lfestival['12-30'].title : (lfestival[lunarFestivalDate] ? lfestival[lunarFestivalDate].title : null),'lYear': year,'lMonth': month,'lDay': day,'Animal': this.getAnimal(year),'IMonthCn': (isLeap ? "\u95f0" : '') + this.toChinaMonth(month),'IDayCn': this.toChinaDay(day),'cYear': y,'cMonth': m,'cDay': d,'gzYear': gzY,'gzMonth': gzM,'gzDay': gzD,'isToday': isToday,'isLeap': isLeap,'nWeek': nWeek,'ncWeek': "\u661f\u671f" + cWeek,'isTerm': isTerm,'Term': Term,'astro': astro,'isVacation': this.isVacation(solarDate)};},isVacation(date) {if (date === "2022-1-1") {return true}if (date === '2022-1-29' || date === '2022-1-30') {return false}return null},/*** 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON* @param y  lunar year* @param m  lunar month* @param d  lunar day* @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]* @return JSON object* @eg:console.log(calendar.lunar2solar(1987,9,10));*/lunar2solar: function (y, m, d, isLeapMonth) {   //参数区间1900.1.31~2100.12.1y = parseInt(y)m = parseInt(m)d = parseInt(d)var isLeapMonth = !!isLeapMonth;var leapOffset = 0;var leapMonth = this.leapMonth(y);var leapDay = this.leapDays(y);if (isLeapMonth && (leapMonth != m)) { return -1; }//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1; }//超出了最大极限值var day = this.monthDays(y, m);var _day = day;//bugFix 2016-9-25//if month is leap, _day use leapDays methodif (isLeapMonth) {_day = this.leapDays(y, m);}if (y < 1900 || y > 2100 || d > _day) { return -1; }//参数合法性效验//计算农历的时间差var offset = 0;for (var i = 1900; i < y; i++) {offset += this.lYearDays(i);}var leap = 0, isAdd = false;for (var i = 1; i < m; i++) {leap = this.leapMonth(y);if (!isAdd) {//处理闰月if (leap <= i && leap > 0) {offset += this.leapDays(y); isAdd = true;}}offset += this.monthDays(y, i);}//转换闰月农历 需补充该年闰月的前一个月的时差if (isLeapMonth) { offset += day; }//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)var stmap = Date.UTC(1900, 1, 30, 0, 0, 0);var calObj = new Date((offset + d - 31) * 86400000 + stmap);var cY = calObj.getUTCFullYear();var cM = calObj.getUTCMonth() + 1;var cD = calObj.getUTCDate();return this.solar2lunar(cY, cM, cD);},/*** 计算全年日历* @param {*} date * @returns */getFullYearDate: function (date) {let dateArr = [];let firstDate = new Date(date.getFullYear() + '/1/1')for (let i = -1; i < 366; i++) {let dd = new Date(firstDate);dd.setDate(dd.getDate() + i);var y = dd.getFullYear();var m = dd.getMonth() + 1;var d = dd.getDate()if (d === 1) {dateArr.push({type: 'month',num: m})}dateArr.push({type: 'day',num: d,date: dd,})}return dateArr}
};
export default calendar;

vue实现垂直无限滑动日历组件相关推荐

  1. vue移动端项目日历组件,月周切换,点击进入上/下一个月

    项目场景: Vue移动端项目的日历组件,移动端如果没有别的特别要求,一般用vant中的日历组件就OK,这里用的另一个.组件是网上找的,原网址:vue-hash-calendar,需要的请自行去看. 我 ...

  2. 17_微信小程序之抖音微视无限滑动视频列表自定义组件编写

    微信小程序之抖音微视无限滑动视频列表自定义组件编写 一.先上效果图 看到上面,你可能首先会想到,使用swiper然后将swiper的circular设置为true,那么,想象一下,假如视频很多的情况下 ...

  3. 微信小程序日历组件(swiper可滑动的日历)

    可滑动的日历组件 根据现实需求自行调整其他 rili.wxml页面 <!--pages/rili/rili.wxml--> <view class="rili"& ...

  4. 基于Vue开发一个日历组件

    最近在做一个类似课程表的需求,需要自制一个日历来支持功能及展现,就顺便研究一下应该怎么开发日历组件. 更新 2.23修复了2026年2月份会渲染多一行的bug,谢谢@深蓝一人童鞋提出的bug,解决方案 ...

  5. vue展示日历 考勤展示_vue实现日历组件

    1.当前组件说明 一个用vue实现的简单日历组件,可以手动设置日历的宽高,未设置时,有默认宽高,设置后,其中的每个日期项的宽高可以根据设定的宽高自适应.可以设置当前选中日期,可以设置时间可用范围,可以 ...

  6. Vue手写一个日历组件

    工作中遇到一个需求是根据日历查看某一天/某一周/某一月的睡眠报告,但是找了好多日历组件都不是很符合需求,只好自己手写一个日历组件,顺便记录一下. 先来看看设计图是什么样式, 跟其他日历有点不一样,这个 ...

  7. vue移动端日历组件 mintUi dateTime picker 设定开始和结束日期

    vue移动端日历组件 mintUi dateTime picker 设定开始和结束日期

  8. vue 日历翻拍效果_VUE实现日历组件功能

    哈哈, 就在昨天笔者刚刚在Github 上发布了一个基于VUE的日历组件.过去做日历都是需要引用 jquery moment 引用 fullCalendar.js 的.几者加起来体积庞大不说,也并不是 ...

  9. 从 0 到 1 用 Vue 封装一个日历组件

    写在前面 双手奉上代码链接: 传送门 - ajun568(https://github.com/ajun568/vue-calendar),点击文末阅读原文直达 双脚奉上最终效果图: 需求分析 需求分 ...

  10. 一个vue的日历组件

    说明: 1.基于element-ui开发的vue日历组件. 地址 更新: 1.增加value-format指定返回值的格式 2.增加头部插槽自定义头部 <ele-calendar >< ...

最新文章

  1. 傅里叶变换之看不懂就掐死我教程
  2. 环信-获取未读消息数量
  3. Android keymaster4.0- device集成笔记
  4. c# json.net xml互转
  5. python 计算过程图片_[Python图像处理]九.图像形态学相关运算
  6. css纯字母或者字母换行显示
  7. 62、滑动窗口的最大值
  8. VC++ 6.0 与VS2008 C++ DEBUG工具(Windows)介绍
  9. JavaScript学习(二十三)—scrollTop练习
  10. C#DataTable2Json(附时间格式化)
  11. 【Sublime Text3 】——代码片段
  12. KALI 2020 软件集成清单——逆向工程(七)
  13. 集线器、交换机、路由器以及端口带宽区别
  14. 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false
  15. 世界的本质是什么---辩证的唯物论
  16. UiBot RPA文字转拼音
  17. 前端架构,有什么能做的?
  18. Java 版spark Streaming 维护kafka 的偏移量
  19. 机器学习 -- 初识决策树
  20. 讯飞星火 VS 文心一言:谁是中文大语言模型的TOP1?

热门文章

  1. 深入浅出统计学读书笔记汇总
  2. 百度文库文档免下载券免费下载方法
  3. python读取、写入txt文本内容
  4. python在屏幕上画画,屏幕上的Python绘图
  5. 博客目录及最新Github下载地址
  6. Sequential Model - 序列模型(RNN循环神经网络)
  7. 怎么用PDF转换器将PDF文件转成txt
  8. 从OpenJDK官网下载JDK源码
  9. linux双系统 引导修复,Linux与windows双系统GRUB引导修复
  10. 最后一周——数模美赛赛前准备总结