****年 **月
// date 为选中月的1号日期
date.setDate(date.getDate() - date.getDay() + 第一位排的是星期几)
如 7月14日 该选中月份1号为 7月1日。则 date.setDate(1-5+0)
即 date.setDate(-4) => 6月26日
如果第一位排的不是周日,而是周六。 date.setDate(1-5+6)
即 date.setDate(2) 此时设置日期比初始1号日期还要大,那么就需要往前推一周
即 date.setDate(2-7) => 6月25日
不可以通过当前选中日期加减一个月!
如:当前选中日期 为 7月31日,此时减去一个月,直接变成了6月31日这个非法的值,2月的日期还不固定。
因此左右切换的时候,传入的永远为当前月的第一天。
如:传入7月1日,减去一个月 为6月1日,不会产生问题
----全部代码----
Utils.js
import { Subject } from './subject'
let transfer = function (date, fmt) {
const _date = new Date(date)
let o = {
'M+': _date.getMonth() + 1, // 月份
'd+': _date.getDate(), // 日
'h+': _date.getHours(), // 小时
'm+': _date.getMinutes(), // 分
's+': _date.getSeconds(), // 秒
'q+': Math.floor((_date.getMonth() + 3) / 3), // 季度
S: _date.getMilliseconds(), // 毫秒
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (_date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (let k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] + '' : ('00' + o[k]).substr(('' + o[k]).length)
)
}
}
return fmt
}
/**
* 用于format日期格式
* @param {*} timeSpan
* @param {*} fmt
* @param {*} formatDateNullValue
*/
export const dateFormat = function (timeSpan, fmt, formatDateNullValue) {
if (!timeSpan) {
if (formatDateNullValue) {
return formatDateNullValue
}
return '无'
}
let date = new Date(timeSpan)
return transfer(date, fmt)
}
/**
* 获取日历header内容 格式为:****年 **月
* @param {*} date
*/
export const getHeaderContent = function (date) {
let _date = new Date(date)
return dateFormat(_date, 'yyyy年 MM月')
}
/**
* 获取当前月的第一天
* @param {*} date
*/
export const getFirstDayOfMonth = function (date) {
let _date = new Date(date)
_date.setDate(1)
return _date
}
/**
* 获取当前月日历的第一天
* @param {*} date
*/
export const getFirstDayOfCalendar = function (date, weekLabelIndex) {
let _date = new Date(date)
_date = new Date(_date.setDate(_date.getDate() - _date.getDay() + weekLabelIndex))
// 如果当前日期大于当前月第一天,则需要减去7天
if (_date > date) {
_date = new Date(_date.setDate(_date.getDate() - 7))
}
return _date
}
/**
* 根据传入index确认weeklabel的顺序
* @param {*} weekIndexOfFirstWeekDay
*/
export const getWeekLabelList = function (weekIndexOfFirstWeekDay) {
let weekLabelArray = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
for (let index = 0; index < weekIndexOfFirstWeekDay; index++) {
let weekLabel = weekLabelArray.shift() || ''
weekLabelArray.push(weekLabel)
}
return weekLabelArray
}
/**
* 启动观察者模式,并且初始化
*/
export const initObserver = function () {
let subject = new Subject()
return subject
}
/**
* 格式化日期为两个单词,例如:‘1’号 格式为 ‘01’
* @param {*} dateNumber
*/
export const formatDayWithTwoWords = function (dateNumber) {
if (dateNumber < 10) {
return '0' + dateNumber
}
return dateNumber
}
/**
* 比较当前日期是否为本月日期,用于进行本月数据高亮显示
* @param {*} firstDayOfMonth
* @param {*} date
*/
export const isCurrentMonth = function (firstDayOfMonth, date) {
return firstDayOfMonth.getMonth() === date.getMonth()
}
/**
* 比较当前日期是否为系统当前日期
* @param {*} date
*/
export const isCurrentDay = function (date) {
let _date = new Date()
return (
date.getFullYear() === _date.getFullYear() &&
date.getMonth() === _date.getMonth() &&
date.getDate() === _date.getDate()
)
}
/**
*
* @param {*} firstDayOfCurrentMonth
* @returns
*/
export const isMoreCurrentDay = function (date) {
let _date = new Date().getTime()
return new Date(date).getTime() > _date
}
/**
* 以传入参数作为基准获取下个月的第一天日期
* @param {*} firstDayOfCurrentMonth
*/
export const getFirstDayOfNextMonth = function (firstDayOfCurrentMonth) {
return new Date(
firstDayOfCurrentMonth.getFullYear(),
firstDayOfCurrentMonth.getMonth() + 1,
1
)
}
/**
* 以传入参数作为基准获取上个月的第一天日期
* @param {*} firstDayOfCurrentMonth
*/
export const getFirstDayOfPrevMonth = function (firstDayOfCurrentMonth) {
return new Date(
firstDayOfCurrentMonth.getFullYear(),
firstDayOfCurrentMonth.getMonth() - 1,
1
)
}
/**
* 以传入参数作为基准获取当前月的日期
* @param {*} firstDayOfCurrentMonth
*/
export const getFirstDayOfCurrntMonth = function (firstDayOfCurrentMonth) {
return new Date(firstDayOfCurrentMonth.getFullYear(), firstDayOfCurrentMonth.getMonth(), 1)
}
subject.js
/*
* Subject
* 内部创建了三个方法,内部维护了一个ObserverList。
*/
export class Subject {
constructor() {
this._observers = new ObserverList()
}
// addObserver: 调用内部维护的ObserverList的add方法
addObserver(observer) {
this._observers.add(observer)
}
// removeObserver: 调用内部维护的ObserverList的removeAt方法
removeObserver(observer) {
this._observers.removeAt(this._observers.indexOf(observer, 0))
}
// notify: 通知函数,用于通知观察者并且执行update函数,update是一个实现接口的方法,是一个通知的触发方法。
notify(context) {
let observerCount = this._observers.count()
for (let i = 0; i < observerCount; i++) {
this._observers.get(i).update(context)
}
}
}
/*
* ObserverList
* 内部维护了一个数组,4个方法用于数组的操作,这里相关的内容还是属于subject,因为ObserverList的存在是为了将subject和内部维护的observers分离开来,清晰明了的作用。
*/
class ObserverList {
constructor() {
this._observerList = []
}
add(obj) {
return this._observerList.push(obj)
}
count() {
return this._observerList.length
}
get(index) {
if (index > -1 && index < this._observerList.length) {
return this._observerList[index]
}
throw new Error(`_observerList ${index} 未知为null`)
}
indexOf(obj, startIndex) {
let i = startIndex
while (i < this._observerList.length) {
if (this._observerList[i] === obj) {
return i
}
i++
}
return -1
}
removeAt(index) {
this._observerList.splice(index, 1)
}
}
export class Observer {
update() {}
}
index.vue
Calendar.vue
CalendarHeader.vue
{{ headerContent }}
回到今天
CalendarBody.vue
-
{{ week }}
-
{{ dayItem.monthDay }}