实现效果
特殊需求
依赖组件
完整代码
import React, { useState, useEffect} from 'react' ;
import { Icon} from 'antd-mobile' ;
import styles from './index.less' ;
import moment from 'moment' ;
import { useSelector} from "dva" ;
moment. locale ( 'zh-cn' ) ;
const dateFormatStr = 'YYYY-MM-DD' ;
const monthFormatterStr = 'YYYY年MM月' ;
const week = [ '星期一' , '星期二' , '星期三' , '星期四' , '星期五' ]
const CustomCalendar = ( ) => {
const { rehydrated} = useSelector ( state => state. _persist) ;
const { everyDayList} = useSelector ( state => state. lianLianYing) ;
const [ currentDate, setCurrentDate] = useState ( moment ( ) ) ;
const [ dayList, setDayList] = useState ( [ ] ) ;
const { loginStatus} = useSelector ( state => state. global) ;
useEffect ( ( ) => {
if ( ! rehydrated || ! loginStatus) return ;
let temp = getMonthFirstDate ( currentDate) . endOf ( 'month' ) ;
initDate ( ) ;
} , [ currentDate, rehydrated, loginStatus, everyDayList] ) ;
const getMonthFirstDate = ( date ) => {
return moment ( date. year ( ) + '-' + ( date. month ( ) + 1 ) + '-01' , dateFormatStr) ;
} ;
const initDate = ( ) => {
let dateArr = [ ] ;
let monthFirstDate = getMonthFirstDate ( currentDate) ;
while ( monthFirstDate. day ( ) === 0 || monthFirstDate. day ( ) === 6 ) {
monthFirstDate. add ( 1 , 'd' ) ;
}
let preMonthDate = moment ( monthFirstDate) . subtract ( 1 , 'M' ) . endOf ( 'month' ) ;
while ( preMonthDate. day ( ) !== 0 && preMonthDate. day ( ) !== 6 && preMonthDate. day ( ) !== 5 ) {
let date = {
date: '' ,
day: preMonthDate. day ( ) ,
}
dateArr. push ( date) ;
preMonthDate. subtract ( 1 , 'd' ) ;
}
while ( monthFirstDate. month ( ) === currentDate. month ( ) ) {
if ( monthFirstDate. day ( ) !== 0 && monthFirstDate. day ( ) !== 6 ) {
const dayVal = everyDayList. find ( ( val ) => val?. init_date === monthFirstDate. format ( 'YYYYMMDD' ) ) ;
let date = {
date: monthFirstDate. date ( ) ,
day: monthFirstDate. day ( ) ,
total: dayVal?. total
}
dateArr. push ( date) ;
}
monthFirstDate. add ( 1 , 'd' ) ;
}
setDayList ( dateArr) ;
} ;
const preMonth = ( ) => {
const newDate = moment ( currentDate) . subtract ( 1 , 'M' ) ;
setCurrentDate ( newDate)
} ;
const nextMonth = ( ) => {
const newDate = moment ( currentDate) . add ( 1 , 'M' ) ;
setCurrentDate ( newDate)
} ;
return < div className= { styles. wrap} >
< div className= { styles. title} >
< div onClick= { preMonth} className= { styles. btn} > < Icon type= { 'left' } / > < / div>
< div> { currentDate. format ( monthFormatterStr) } < / div>
{ currentDate. isBefore ( moment ( ) , 'month' ) ?
< div onClick= { nextMonth} className= { styles. btn} > < Icon type= { 'right' } / > < / div> : < div className= { styles. btn} / > }
< / div>
< div className= { styles. week} >
{ week. map ( ( item, index ) => {
return < div className= { styles. weekText} key= { index} > { item} < / div>
} ) }
< / div>
< div className= { styles. days} >
{ dayList. map ( ( item, index ) => {
return < div className= { styles. day} key= { index} >
< div className= { styles. date} > { item?. date} < / div>
{ item?. date ?
( item?. total ? (
< div className= { item?. total > 0 ? styles. red : styles. green} > { item?. total} < / div>
) : < div className= { styles. grey} > -- < / div> )
: < div/ > }
< / div>
} ) }
< / div>
< / div> ;
} ;
export default CustomCalendar;
@import ( reference) '../../styles/index.less' ;
.wrap {
padding : 5*@rem ;
.title {
display : flex;
justify-content : center;
align-items : center;
padding-bottom : 10*@rem ;
.btn {
width : 50*@rem ;
}
& > div {
display : flex;
justify-content : center;
align-items : center;
font-size : 20*@rem ;
}
}
.week {
display : flex;
justify-content : space-around;
.weekText {
text-align : right;
flex : 20%;
padding-right : 10*@rem ;
}
}
.days {
display : flex;
justify-content : flex-start;
flex-wrap : wrap;
.day {
width : 20%;
padding-right : 5*@rem ;
border-top : solid @greyBorder 0.1px;
padding-bottom : 5*@rem ;
padding-top : 5*@rem ;
color : white;
.date {
height : 30*@rem ;
display : flex;
justify-content : flex-end;
align-items : flex-end;
font-size : 16*@rem ;
color : black;
padding-right : 5*@rem ;
}
.red {
display : flex;
justify-content : flex-end;
align-items : center;
width : 100%;
background : #FF6764;
border-radius : 2*@rem ;
padding-right : 5*@rem ;
font-size : 14*@rem ;
}
.green {
display : flex;
justify-content : flex-end;
align-items : center;
background : #91C874;
border-radius : 2*@rem ;
width : 100%;
padding-right : 5*@rem ;
font-size : 14*@rem ;
}
.grey {
display : flex;
justify-content : flex-end;
align-items : center;
background : #e1e4ea;
border-radius : 2*@rem ;
width : 100%;
padding-right : 5*@rem ;
font-size : 14*@rem ;
}
}
}
}