123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919 |
- <template>
- <view class="lunc-calendar">
- <!-- 头部上下月按钮及月份 -->
- <view class="header">
- <view class="head-icon head-pre-month" v-show="showChangeBtn" @click="changeMonthOrWeek('prev')"></view>
- <view class="head-month">{{selDate.year+'年'+(selDate.month<10?'0'+selDate.month:selDate.month)+'月'}}</view>
- <view class="head-icon head-next-month" v-show="showChangeBtn" @click="changeMonthOrWeek('next')"></view>
- <view class="go-to-today" v-show="showToday" @click="goToday">今</view>
- </view>
- <!-- 星期 -->
- <view class="week-area">
- <!-- <view class="week-font" v-for="(item, index) in weekArr" :key="index ">{{ weekType + '' + item }}</view> -->
- <view class="week-font" v-for="(item, index) in weekArr" :key="index ">{{ item }}</view>
- </view>
- <!-- 日历 -->
- <swiper class="calendar-data" :current="shrinkType?tranCurrent:tranIndex" circular :duration="tranDuration"
- @change="swiperChange" @animationfinish="swiperEndChange" :style="{height:shrinkType?'56px':'266px'}">
- <swiper-item class="swiper-item swiper-prev-item" v-for="(a, i) in getAllData" :key="i">
- <view class="month-bg" v-if="showMonthBg">{{ getMontBg }}</view>
- <view class="month-days" :class="shrinkType?'item-week':''">
- <view class="week-days" v-for="(b, j) in a" :key="j">
- <view class="day" v-for="(c, k) in b" :key="k" @click="clickDay(c)">
- <view class="day-info"
- :class="[c.dayClass, getIsSelDay(c)?'is-sel':'', c.dayType!='normal'?'un-month':'']">
- <text class="day-solar">{{ c.day }}</text>
- <template v-if="showLunar || c.sign && c.sign.length > 0">
- <text class="day-tag" v-if="c.sign && c.sign.length > 0"></text>
- <text class="day-sign"
- v-if="c.sign && c.sign.length > 0">{{ c.sign[0].title }}</text>
- <text class="day-lunar" v-else>{{c.dayLunar}}</text>
- </template>
- </view>
- </view>
- </view>
- </view>
- </swiper-item>
- </swiper>
- <!-- 收缩按钮 -->
- <view class="shrink" v-if="showShrink" @click="changeShrink">
- <text class="shrink-btn" :class="shrinkType?'shrink-open':'shrink-close'"></text>
- </view>
- </view>
- </template>
- <script>
- let {
- calendar
- } = require("./calendar.js");
- /**
- * @property {Boolean} showLunar = [true|false] 是否显示农历,默认false
- * @property {Boolean} showMonthBg = [true|false] 是否显示月份背景,默认true
- * @property {Boolean} showChangeBtn = [true|false] 是否显示上月下月箭头按钮,默认true
- * @property {String} firstDayOfWeek = [monday|sunday] 周几为每周的第一天,默认monday
- * @value monday 每周从周一开始(默认)
- * @value sunday 每周从周日开始
- * @property {String} weekType = [''|周|星期] 星期的前缀;如周一周二或星期一星期二,为空则只显示一、二等;不用预设值时可自定义前缀,填的值即为星期前缀;默认周
- * @value '' 星期显示:只显示一、二等
- * @value 周 星期显示:周一、周二等(默认)
- * @value 星期 星期显示:星期一、星期二等
- * @property {Boolean} weekend = [true|false] 周末标红(周六周日日期用红色字体),默认true
- * @property {Boolean} showShrink = [true|false] 是否显示收缩按钮,可显示一周的日期,默认false
- * @property {String} shrinkState = [week|month] 收缩状态,默认month
- * @value week 默认打开显示周数据(收起状态)
- * @value month 默认打开显示月数据(展开状态)
- * @property {Array} signList 标记数组,若当前有多个标记,则显示最后一个,期待格式[{date: '2021-09-10', title: '生日', info: '八月初四张三生日'}]
- * @event {Function()} dayChange 点击日期触发事件
- * @event {Function()} monthChange 切换月份触发事件
- * @event {Function()} shrinkClick 收缩和展开时触发事件
- */
- export default {
- name: 'LuncCalendar',
- props: {
- //是否显示农历
- showLunar: {
- type: Boolean,
- default: false
- },
- //是否显示月份背景
- showMonthBg: {
- type: Boolean,
- default: true
- },
- //是否显示上月下月按钮
- showChangeBtn: {
- type: Boolean,
- default: true
- },
- //每周的周几为第一天
- firstDayOfWeek: {
- type: String,
- default: 'sunday'
- },
- //每周的周几为第一天
- weekType: {
- type: String,
- default: ''
- },
- //周末标红
- weekend: {
- type: Boolean,
- default: false
- },
- //是否可收缩,收起来后以周显示
- showShrink: {
- type: Boolean,
- default: true
- },
- // 默认打开状态(收起或展开)
- shrinkState: {
- type: String,
- default: 'month'
- },
- //标记
- signList: {
- type: Array,
- default () {
- return []
- }
- }
- },
- data() {
- return {
- weekArr: ['一', '二', '三', '四', '五', '六', '日'], //星期数组
- today: {}, //今天日期 -> year, month, day
- selDate: {}, //选中日期信息 -> year, month, day
- allMonthList: [], // 月份数据 -> [[[周],[周]],[月],[月]]
- tranIndex: 1, // 月份轮播所在位置
- allWeekList: [], // 周月份数据 -> [[[周]],[月],[月]]
- tranCurrent: 1, // 周轮播所在位置
- tranDuration: 300, //轮播时间(单位毫秒)
- signArr: this.signList, // 标记列表
- showToday: false, //显示回到今天(非当月才显示)
- shrinkType: false, // 收缩状态,true:收起(显示周),false展开(显示月)
- deterChange: true, // 防止切换月份过快
- }
- },
- created() {
- let nd = new Date();
- this.today = {
- year: nd.getFullYear(),
- month: nd.getMonth() + 1,
- day: nd.getDate()
- }
- if (this.firstDayOfWeek == "sunday") this.weekArr = ['日', '一', '二', '三', '四', '五', '六'];
- this.initDate();
- },
- watch: {},
- computed: {
- getAllData() { // 切换周或月时,展示的数据不同
- return this.shrinkType ? this.allWeekList : this.allMonthList;
- },
- getMontBg() { // 获取当前月背景
- let monthBg = this.selDate.month;
- return !this.shrinkType ? (monthBg < 10 ? '0' + monthBg : monthBg) : '';
- },
- getIsSelDay() { // 判断是否是选中日期
- return (d) => {
- let {
- year,
- month,
- day
- } = this.selDate;
- return year == d.year && month == d.month && day == d.day
- }
- },
- },
- methods: {
- initDate() { // 初始化日期
- this.selDate = JSON.parse(JSON.stringify(this.today));
- let monthList = this.getMonthData(this.selDate); // 获取当月数据
- let prevMonthList = this.getMonthData(this.getMonthDate(this.selDate, -1)); // 上月数据
- let nextMonthList = this.getMonthData(this.getMonthDate(this.selDate)); // 下月数据
- this.allMonthList = [prevMonthList, monthList, nextMonthList]
- this.tranIndex = 1;
- if (this.shrinkState == "week" && !this.shrinkType) this.changeShrink();
- },
- /**
- * 根据指定日期获取当月的数据
- * @param {Object} date = { year, month, day } 指定的日期
- */
- getMonthData(date) {
- const {
- year,
- month,
- day
- } = date; //指定的日期
- let maxDay = new Date(year, month, 0).getDate(); //当前月最大日期
- let firstWeek = new Date(year + "/" + month + "/1").getDay(); //月份1号的星期数
- if (this.firstDayOfWeek == "monday") firstWeek = firstWeek - 1 < 0 ? 6 : firstWeek - 1;
- let list = [];
- //每月显示42天,6周,每周7天
- for (var i = 0; i < 42; i++) {
- let dayInfo = {}; // 每天的详细信息
- if (i < firstWeek) { //指定月份上月的最后几天
- let {
- year,
- month
- } = this.getMonthDate(date, -1);
- let preMaxDay = new Date(year, month, 0).getDate(); //上月最大日期
- let day = preMaxDay - firstWeek + i + 1;
- dayInfo = this.getDayInfo({
- year,
- month,
- day
- }, 'prev');
- } else if (i > maxDay + firstWeek - 1) { //指定月份下月的前几天
- let {
- year,
- month
- } = this.getMonthDate(date);
- let day = i - maxDay - firstWeek + 1;
- dayInfo = this.getDayInfo({
- year,
- month,
- day
- }, 'next');
- } else {
- let day = i - firstWeek + 1;
- dayInfo = this.getDayInfo({
- year,
- month,
- day
- }, 'normal');
- }
- if (i % 7 == 0) list.push(new Array());
- list[list.length - 1].push(dayInfo);
- }
- return list;
- },
- /**
- * 获取指定日期的详细信息,包括农历节假日等
- * @param {Object} date = { year, month, day } 指定的日期
- * @param {String} dayType = [prev|next|normal] 日期类型,上月|下月|当前月
- */
- getDayInfo(date, dayType) {
- const {
- year,
- month,
- day
- } = date;
- let isToday = false; //是否今天
- if (year == this.today.year && month == this.today.month && day == this.today.day) isToday = true;
- let week = new Date(year + "/" + month + "/" + day).getDay(); //星期数
- let lunar = calendar.solar2lunar(year, month, day); //农历
- let dayLunar = lunar.IDayCn == '初一' ? lunar.IMonthCn + lunar.IDayCn : lunar.IDayCn;
- if (lunar.festival) dayLunar = lunar.festival; // 阳历节日
- else if (lunar.lunarFestival) dayLunar = lunar.lunarFestival; // 农历节日
- else if (lunar.Term) dayLunar = lunar.Term; // 节气
- let holidayArr = ["元旦", "春节", "清明节", "劳动节", "端午节", "中秋节", "国庆节"];
- let isHoliday = false;
- if (holidayArr.indexOf(dayLunar) != -1) isHoliday = true;
- let dayInfo = {
- date: year + "-" + month + "-" + day,
- year,
- month,
- day,
- week,
- lunar, // 农历
- dayLunar, // 显示的农历
- isToday, // 是否是今日
- isHoliday, // 是否是节假日
- dayType, // 日期类型,上月、下月或当前月
- sign: this.getSignByDate(date)
- }
- let dayClass = this.getDayClass(dayInfo);
- dayInfo["dayClass"] = dayClass;
- return dayInfo;
- },
- /**
- * 根据日期详细信息添加对应的class
- * @param {Object} dayInfo 日期详情
- */
- getDayClass(dayInfo) {
- let dClass = "";
- if (dayInfo.isToday) dClass += ' is-today'; // 今天日期
- if (dayInfo.isHoliday) dClass += ' is-holiday'; // 法定假日
- if (this.weekend && (dayInfo.week == 0 || dayInfo.week == 6)) dClass += ' week-end'; // 周末标红
- return dClass;
- },
- /**
- * 根据日期获取日期对应的事件
- * @param {Object} date = { year, month, day } 指定的日期
- */
- getSignByDate(date) {
- const {
- year,
- month,
- day
- } = date;
- let dayDateS = new Date(year + "/" + month + "/" + day + " 00:00:00").getTime();
- let dayDateE = new Date(year + "/" + month + "/" + day + " 23:59:59").getTime();
- let daySign = [];
- this.signArr.map(sign => {
- let signDate = sign.date.replace(/-/g, '/');
- let signTimes = new Date(sign.date).getTime();
- if (signTimes >= dayDateS && signTimes <= dayDateE) daySign.push(sign)
- })
- return daySign;
- },
- /**
- * 获取月份数据
- * @param {String} type=[pre|next]
- */
- getOtherData(type) {
- let nowMont = this.getMonthDate(this.selDate, type == 'prev' ? -1 : 1); // 获取当前月份
- this.selDate = nowMont; // 切换月份后设置选中的日期
- let monthData = this.getMonthData(this.getMonthDate(nowMont, type == 'prev' ? -1 : 1));
- // 获取上月或下月轮播所在位置
- let current = this.getTranIndex().prevNum;
- if (type == "next") current = this.getTranIndex().nextNum;
- this.allMonthList.splice(current, 1, monthData);
- this.judgeShowToday();
- this.returnMonthChange(type);
- },
- /**
- * 获取周数据
- * @param {String} type=[pre|next]
- */
- getOtherWeekData(type) {
- let oldSel = this.selDate; // 原选中的日期
- let newSel = this.getDateByDateAndDay(oldSel, type == 'prev' ? -7 : 7); // 获取7天前或后的日期
- if (oldSel.month != newSel.month) { // 跨月,先设置跨月后的月历
- // 设置月轮播位置
- let current = this.getTranIndex("month").prevNum;
- if (type == "next") current = this.getTranIndex("month").nextNum;
- this.tranIndex = current;
- this.getOtherData(type);
- }
- this.selDate = newSel;
- this.getWeekData(type);
- this.judgeShowToday();
- },
- // 从月历中获取周数据,切换周后获取上周或下周数据
- getWeekData(type) {
- const {
- prevNum: prevIndex,
- nowNum: nowIndex,
- nextNum: nextIndex
- } = this.getTranIndex("month");
- const {
- prevNum: prevCurrent,
- nowNum: nowCurrent,
- nextNum: nextCurrent
- } = this.getTranIndex("week");
- const {
- year: selYear,
- month: selMonth,
- day: selDay
- } = this.selDate;
- let sDate = selYear + "-" + selMonth + "-" + selDay
- let prevMonthList = this.allMonthList[prevIndex];
- let nowMonthList = this.allMonthList[nowIndex];
- let nextMonthList = this.allMonthList[nextIndex];
- for (let i = 0; i < nowMonthList.length; i++) {
- for (let j = 0; j < nowMonthList[i].length; j++) {
- if (sDate == nowMonthList[i][j].date) {
- this.returnDayChange(nowMonthList[i][j]); // 返回选中的日期
- if (type == "next") {
- this.allWeekList.splice(nextCurrent, 1, [nowMonthList[i + 1]]);
- if (i == 5) this.allWeekList.splice(nextCurrent, 1, [nextMonthList[1]]);
- } else {
- this.allWeekList.splice(prevCurrent, 1, [nowMonthList[i - 1]]);
- if (i == 0) {
- for (let k = prevMonthList.length - 1; k >= 0; k--) {
- if (prevMonthList[k][6].dayType == "normal") {
- this.allWeekList.splice(prevCurrent, 1, [prevMonthList[k]]);
- break;
- }
- }
- }
- }
- break;
- }
- }
- }
- },
- // 根据月份数据获取周数据,相当初始化周数据
- getAllWeekData() {
- const {
- prevNum,
- nowNum,
- nextNum
- } = this.getTranIndex("month");
- const {
- year: selYear,
- month: selMonth,
- day: selDay
- } = this.selDate;
- let sDate = selYear + "-" + selMonth + "-" + selDay; // 选中的日期
- let allWeekList = [
- [],
- [],
- []
- ];
- let prevMonthList = this.allMonthList[prevNum];
- let nowMonthList = this.allMonthList[nowNum];
- let nextMonthList = this.allMonthList[nextNum];
- for (let i = 0; i < nowMonthList.length; i++) {
- for (let j = 0; j < nowMonthList[i].length; j++) {
- if (sDate == nowMonthList[i][j].date) {
- allWeekList[0][0] = nowMonthList[i - 1];
- allWeekList[1][0] = nowMonthList[i];
- allWeekList[2][0] = nowMonthList[i + 1];
- if (i == 5) {
- allWeekList[2][0] = nextMonthList[1];
- } else if (i == 0) {
- for (let k = prevMonthList.length - 1; k >= 0; k--) {
- if (prevMonthList[k][6].dayType == "normal") {
- allWeekList[0][0] = prevMonthList[k];
- break;
- }
- }
- }
- break;
- }
- }
- }
- this.allWeekList = allWeekList;
- },
- // 滑动切换结束
- swiperEndChange() {
- this.tranDuration = 300;
- },
- // 滑动切换月份或周
- swiperChange(e) {
- let current = e.detail.current;
- let oldIndex = this.shrinkType ? this.tranCurrent : this.tranIndex;
- let type = (oldIndex - current == -1 || oldIndex - current == 2) ? 'next' : 'prev';
- if (this.shrinkType) {
- this.tranCurrent = current;
- if (current != oldIndex) this.getOtherWeekData(type);
- } else {
- this.tranIndex = current;
- if (current != oldIndex) this.getOtherData(type);
- }
- },
- // 点击切换月份或周(上月下月切换或上周下周切换)type = [prev|next] 切换类型
- changeMonthOrWeek(type) {
- if (!this.deterChange) return;
- this.deterChange = false;
- setTimeout(_ => {
- this.deterChange = true;
- }, 400); // 防止点击过快
- this.tranDuration = 300;
- let tranType = this.shrinkType ? 'week' : 'month';
- let current = this.getTranIndex(tranType).prevNum;
- if (type == "next") current = this.getTranIndex(tranType).nextNum;
- if (tranType == "week") {
- this.tranCurrent = current;
- this.getOtherWeekData(type);
- } else {
- this.tranIndex = current;
- this.getOtherData(type);
- }
- },
- // 点击收缩按钮,切换显示月份或显示周
- changeShrink() {
- this.shrinkType = !this.shrinkType;
- if (this.tranDuration != 0) this.tranDuration = 0;
- if (this.shrinkType) {
- this.tranCurrent = 1;
- this.getAllWeekData();
- }
- this.returnShrinkChange();
- this.judgeShowToday();
- },
- // 点击回到今天
- goToday() {
- if (this.tranDuration != 0) this.tranDuration = 0;
- let oldDate = JSON.parse(JSON.stringify(this.selDate));
- this.initDate();
- if (this.shrinkType) {
- this.tranCurrent = 1;
- this.getAllWeekData();
- let today = this.today;
- // 判断是否需要触发改变月份事件
- if (oldDate.year != today.year || oldDate.month != today.month) {
- this.returnMonthChange("today");
- } else {
- this.returnDayChange(this.today);
- }
- } else {
- this.returnMonthChange("today"); // 事件
- }
- this.judgeShowToday();
- },
- // 点击日期
- clickDay(dayInfo) {
- let {
- year,
- month,
- day
- } = this.selDate;
- if (day == dayInfo.day && month == dayInfo.month && year == dayInfo.year) return;
- let oldSel = JSON.parse(JSON.stringify(this.selDate));
- this.selDate.day = dayInfo.day;
- if (oldSel.month != dayInfo.month) {
- if (!this.shrinkType) {
- this.changeMonthOrWeek(dayInfo.dayType);
- return;
- } else {
- this.selDate.year = dayInfo.year;
- this.selDate.month = dayInfo.month;
- let current = this.getTranIndex("month").prevNum;
- if (dayInfo.dayType == "next") current = this.getTranIndex("month").nextNum;
- this.tranIndex = current;
- let monthData = this.getMonthData(this.getMonthDate(this.selDate, dayInfo.dayType == 'prev' ? -1 :
- 1));
- let current2 = this.getTranIndex("month").prevNum;
- if (dayInfo.dayType == "next") current2 = this.getTranIndex("month").nextNum;
- this.allMonthList.splice(current2, 1, monthData); // 设置上月或下月数据
- }
- this.returnMonthChange(dayInfo.dayType);
- } else {
- this.returnDayChange(dayInfo);
- }
- },
- // 判断是否需要显示回到今天(非本月或本周时显示)
- judgeShowToday() {
- const {
- year,
- month,
- day
- } = this.today;
- const {
- year: selYeat,
- month: selMonth,
- day: selDay
- } = this.selDate;
- if (this.shrinkType) { // 显示的周
- let selTimes = new Date(selYeat, selMonth - 1, selDay).getTime(); // 选中日期的时间戳
- let week = new Date(year, month - 1, day).getDay(); // 今天星期
- let firstWD = this.getDateByDateAndDay(this.today, -week + (this.firstDayOfWeek == "monday" ? 1 : 0));
- let lastWD = this.getDateByDateAndDay(this.today, 6 - week + (this.firstDayOfWeek == "monday" ? 1 :
- 0));
- let firstTimes = new Date(firstWD.year, firstWD.month - 1, firstWD.day).getTime();
- let lastTimes = new Date(lastWD.year, lastWD.month - 1, lastWD.day).getTime();
- if (selTimes > lastTimes || selTimes < firstTimes) this.showToday = true;
- else this.showToday = false;
- } else {
- if (year != selYeat || month != selMonth) this.showToday = true;
- else this.showToday = false;
- }
- },
- // 重新设置标记
- setSignList() {
- this.allMonthList.map(month => {
- month.map(week => {
- week.map(day => {
- day.sign = this.getSignByDate({
- year: day.year,
- month: day.month,
- day: day.day
- })
- })
- })
- })
- },
- /**
- * 添加标记
- * @param {Array} list 需要添加的标记
- */
- addSignList(list) {
- let signArr = this.signArr.concat(list);
- this.signArr = signArr;
- this.setSignList();
- },
- /**
- * 删除标记
- * 根据date和title共同判断是否删除
- * @param {Array} list 需要删除的标记
- */
- deleteSignList(list) {
- let signArr = this.signArr;
- signArr = signArr.filter(s => {
- if (list.find(l => l.date == s.date && l.title == s.title)) return false
- else return true;
- })
- this.signArr = signArr;
- this.setSignList();
- },
- /**
- * 事件 - 设置返回日期
- * @param {Object} dayInfo 日期详情
- */
- returnDayChange(dayInfo) {
- let {
- year,
- month,
- day
- } = dayInfo;
- let dayDate = year + "-" + (month < 10 ? '0' + month : month) + "-" + (day < 10 ? '0' + day : day)
- let returnData = {
- date: dayDate,
- year: year,
- month: month,
- day: day,
- week: dayInfo.week,
- daySign: dayInfo.sign
- }
- if (this.showLunar) returnData["lunar"] = dayInfo.lunar;
- this.$emit("dayChange", returnData);
- },
- /**
- * 事件 - 设置返回月份
- * @param {String} type 类型
- */
- returnMonthChange(type) {
- let selDate = this.selDate.year + "-" + this.selDate.month + "-" + this.selDate.day;
- let monthList = this.allMonthList.flat().flat(); // 二维转一维
- let dayInfo = monthList.find(day => day.date == selDate);
- this.returnDayChange(dayInfo)
- this.$emit("monthChange", {
- year: dayInfo.year,
- month: dayInfo.month,
- type: type
- });
- },
- /**
- * 事件 - 返回收缩状态
- */
- returnShrinkChange() {
- let type = this.shrinkType ? 'week' : 'month'
- this.$emit("shrinkClick", type);
- },
- /**
- * 获取上一个或下一个轮播位置
- * @param {String} type = [month|week] 轮播类型,月轮播(tranIndex),周轮播(tranCurrent)
- * @returns {Object} {prevNum, nowNum, nextNum}
- */
- getTranIndex(type = 'month') {
- let current = this.tranIndex;
- if (type == "week") current = this.tranCurrent;
- let prevNum = current - 1 < 0 ? 2 : current - 1;
- let nowNum = current;
- let nextNum = current + 1 > 2 ? 0 : current + 1;
- return {
- prevNum,
- nowNum,
- nextNum
- }
- },
- /**
- * 根据日期获取几天后的日期
- * @param {Object} date = {year, month, day} 当前日期
- * @param {Number} day 当前日期的几天前或几天后(负数)
- * @returns {Object} {year, month, day}
- */
- getDateByDateAndDay(date, num) {
- let dTime = new Date(date.year + "/" + date.month + "/" + date.day).getTime() + num * 24 * 60 * 60 * 1000;
- let nd = new Date(dTime);
- return {
- year: nd.getFullYear(),
- month: nd.getMonth() + 1,
- day: nd.getDate()
- }
- },
- /**
- * 获取几个月前或后的日期
- * @param {Object} date = {year, month, day} 当前日期
- * @param {Number} num 当前日期的num月前或后,默认1月后(下月)
- * @returns {Object} {year, month, day}
- */
- getMonthDate(date, num = 1) {
- let nextMonth = date.month + num;
- let diffYear = parseInt(Math.abs(nextMonth) / 12);
- let year = date.year;
- let month = nextMonth;
- if (nextMonth > 12) {
- year = date.year + diffYear;
- month = nextMonth % 12;
- } else if (nextMonth < 1) {
- year = date.year - (diffYear + 1);
- month = nextMonth + 12 * (diffYear + 1);
- }
- let monthMaxDay = new Date(year, month, 0).getDate(); // 月份最大日期
- let day = date.day > monthMaxDay ? monthMaxDay : date.day;
- return {
- year,
- month,
- day
- }
- },
- }
- }
- </script>
- <style lang="scss">
- .lunc-calendar {
- background-color: #FFF;
- // 头部
- .header {
- display: flex;
- flex-direction: row;
- justify-content: center;
- position: relative;
- height: 90rpx;
- line-height: 90rpx;
- border-bottom: 1px solid #DDD;
- .head-month {
- font-size: 36rpx;
- padding: 0 40rpx;
- }
- .go-to-today {
- position: absolute;
- right: 0;
- top: 26rpx;
- padding: 8rpx 12rpx 8rpx 22rpx;
- background-color: rgba(255, 184, 0, 1);
- border-radius: 22rpx 0 0 22rpx;
- font-size: 24rpx;
- line-height: 24rpx;
- color: #FFF;
- }
- .head-icon {
- width: 20rpx;
- height: 20rpx;
- margin-top: 36rpx;
- }
- .head-icon::after {
- content: '';
- display: block;
- width: 18rpx;
- height: 18rpx;
- border-top: 2rpx solid #606266;
- border-left: 2rpx solid #606266;
- }
- .head-icon.head-pre-month {
- transform: rotate(-45deg);
- }
- .head-icon.head-next-month {
- transform: rotate(135deg);
- }
- }
- // 星期
- .week-area {
- display: flex;
- flex-direction: row;
- align-items: center;
- border-bottom: 1px solid #EEE;
- padding: 16rpx 0;
- // margin: 0 10rpx;
- .week-font {
- flex: 1;
- text-align: center;
- color: #666;
- font-size: 28rpx;
- padding: 30rpx;
- }
- }
- // 日历
- .calendar-data {
- // transition: all 300ms;
- .swiper-item {
- position: relative;
- display: -webkit-box;
- .month-bg {
- position: absolute;
- font-size: 240px;
- font-weight: bold;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -55%);
- color: #EEE;
- opacity: 0.4;
- z-index: -1;
- word-break: initial;
- }
- .month-days {
- width: 100%;
- margin-top: 14rpx;
- position: relative;
- // transition: all 300ms;
- .week-days {
- display: flex;
- flex-direction: row;
- .day {
- flex: 1;
- width: 14.28%;
- text-align: center;
- height: 84rpx;
- color: #000;
- padding: 0 6rpx;
- box-sizing: border-box;
- .day-info {
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: flex-start;
- align-items: center;
- position: relative;
- .day-solar {
- display: block;
- font-size: 34rpx;
- line-height: 34rpx;
- margin-top: 18rpx;
- }
- .day-lunar,
- .day-sign {
- color: #909399;
- font-size: 24rpx;
- line-height: 24rpx;
- transform: scale(0.8);
- white-space: nowrap;
- }
- .day-sign {
- color: #F75858 !important;
- }
- .day-tag {
- content: "";
- position: absolute;
- top: 8rpx;
- right: 8rpx;
- width: 10rpx;
- height: 10rpx;
- border-radius: 50%;
- display: inline-block;
- background-color: #F75858;
- }
- }
- // 非当月日期
- .day-info.un-month {
- opacity: 0.25;
- transition: all 300ms;
- }
- .is-today {
- background-color: #b8b8b8a3 ;
- border-radius: 6rpx;
- color: #4CB2B6;
- }
- // 今天日期
- .is-today .day-solar,
- .is-today .day-sign,
- .is-today .day-lunar {
- color: #4CB2B6;
- }
- // 周末
- .week-end .day-solar {
- color: #FF9595;
- }
- // 法定假日
- .is-holiday .day-solar,
- .is-holiday .day-sign,
- .is-holiday .day-lunar {
- color: #F75858 !important;
- }
- // 当前选中的日期
- .is-sel {
- background-color: #4CB2B6;
- border-radius: 6rpx;
- color: #fff;
- }
- // 今天日期
- .is-sel .day-solar,
- .is-sel .day-sign,
- .is-sel .day-lunar {
- color: #FFFFFF;
- }
- }
- }
- .week-days.week-hide {
- display: none;
- }
- }
- .item-week {
- .un-month {
- opacity: 1 !important;
- }
- }
- }
- }
- // 收缩按钮
- .shrink {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 60rpx;
- border-top: 1px solid #DDD;
- .shrink-btn {
- width: 32rpx;
- height: 32rpx;
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAMhJREFUOE/dky8LAkEQxd9w0WjV72KxWXfggmAyWWzXxHbNYjIJhoOZarvid9FqNB4jCyes3h9OLghu3fceb36zS+h5qKcf/xYgIisAayJKnHMa8lFVZ2YpgB0z7193FQYisgCwAXA3s8QLicgbhwC2zHwMgxshBkFeXzE2Nvh2rW8NsiybRFE0ZuZTXZCIzIuiuMZxfKltICJTAAciegDwIM9eqKozAKmZDQAsmTlvHSGY/1YKR00cWl9iGYRP8p220BXm7//CE8WyQBHBXZb9AAAAAElFTkSuQmCC);
- // transition: all 300ms;
- }
- .shrink-close {
- transform: rotate(-180deg);
- }
- }
- }
- </style>
|