手写一个日历组件

842 阅读1分钟
import React,{useState} from 'react';
import styles from './index.less';
import moment from 'moment';
const dateList :any[]=[];
export default () => {
  const [year,setYear] = useState(moment().year());
  const [month,setMonth] = useState(moment().months());
  const [date,setDate] = useState(moment().date())
  
  function getData(){
   	 const arr:object[] = [];
      var monthDay = moment().year(year).month(month).daysInMonth(); //  本月有几天
      var firstDayweek = moment().year(year).month(month).startOf('month').weekday();//本月一号星期几
      var lastMonthDay = moment().year(year).month(month-1).daysInMonth(); //上个月最后一天是几号
      //放上月
      while(firstDayweek--){
       var i = lastMonthDay--
        arr.unshift({
          date:i,
          val:'prev',
          full:moment(`${year}-${month}-${i}`).format('YYYY-MM-DD')
        })
      }
      //放本月
      for(let i = 1;i<=monthDay;i++){
        let val = 'now';
        if(moment(`${year}-${month+1}-${i}`).format('YYYY-MM-DD')=== moment().format('YYYY-MM-DD')){
          val  = val+' '+'today'
        }
        arr.push({
          date:i,
          val:val,
          full:moment(`${year}-${month+1}-${i}`).format('YYYY-MM-DD')
        })
      }
     
      //放下月
      var count = 1;
      var target = arr.length<=35?35:42;
      while(arr.length< target){
        let a = count++;
        arr.push({
          date:a,
          val:'next',
          full:moment(`${year}-${month+2}-${a}`).format('YYYY-MM-DD')
        })
      }
      
      //变成二维数组
      var erweiArr = [];
      while(arr.length>0){
        erweiArr.push(arr.splice(0,7))
      }

      return  erweiArr.map((item,key)=>(
        <tr key={key}>
          {
            item.map((i,k)=>(
              <td key={k}>
                <span 
                className={i.val}
                onDoubleClick={(e)=>{
                 choseSingle(e,i)
                }}
                onClick={(e)=>{showDate(e,i)}}
                
                >{i.date}</span>
              </td>
            ))
          }
        </tr>
      ))
  }
  function init(){
    dateList.forEach(item=>{
      item.style.background='transparent';
    })
  }
  function showDate(e,i){
   init();
   let a = e.currentTarget;
    dateList.push(a)
    if(dateList.length>2){
     let b = dateList.shift()
     console.log(b)
      b.style.backgroundColor='transparent';
    }
    dateList.forEach(item=>{
      console.log('rrr',item)
      item.style.background='red';
    })
  }

  function choseSingle(e,i){
    dateList.forEach(item=>{
      item.style.backgroundColor='transparent'
    })
    e.currentTarget.style.backgroundColor ='red';
    dateList.push(e.currentTarget)
  }

  return (
    <div style={{width:600}}>
      <div className={styles.header}>
      <div onClick={()=>{setMonth(month-1);init()}}> 上个月</div>
        <div>
          <p>{month+1}月</p>
          <p>{year}</p>
        </div>
        <div>下个月</div>
      </div>
    <table>
      <thead>
        <tr>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        {getData()}
      </tbody>
    </table>
    </div>
  );
}

index.less

.header {
  display: flex;
  >div {
    flex: 1;
  }
}
table {
  td,
  th {
    width: 60px;
    text-align: center;
  }
  td {
    span {
      display: inline-block;
      line-height: 30px;
      width: 30px;
      height: 30px;
      border-radius: 15px;
    }
  }
}

span[class='prev'],
span[class='next'] {
  color: #999;
}

span[class='now today'] {
  background: green;

  color: #fff;

}

span[class~='checked'] {
  background: red;
}

结果 样式可以自己再优化下