结合tailwindcss封装的react日历组件

  const [curDate, setCurDate] = useState(moment().format('YYYY-MM-DD'))
  const [curYear, setCurYear] = useState(parseInt(moment().format('YYYY')))
  const [curMonth, setCurMonth] = useState(parseInt(moment().format('MM')))
  const [curDay, setCurDay] = useState(parseInt(moment().format('DD')))
  const [defaultCurDay, setDefCurDay] = useState(parseInt(moment().format('DD')))
  const [defaultCurYear, setDefCurYear] = useState(parseInt(moment().format('YYYY')))
  const [defaultCurMonth, setDefCurMonth] = useState(parseInt(moment().format('MM')))

  /*获取当月天数*/
  const [daysInMon, setDaysInMonth] = useState(moment(new Date(`${curYear}-${curMonth}`), "YYYY-MM").daysInMonth())
  /*获取当月第一天是星期几*/
  const [startWeekDay, setStartWeekDay] = useState(compStartWeekDayIndex)/*moment().startOf('month').weekday()*/
  /*获取上个月月份*/
  const [lastMonth, setLastMonth] = useState(moment().subtract(1, 'month').format('MM'))
  /*获取上个月最后一天几号*/
  const [lastMonthDay, setLastMonthDay] = useState(moment().subtract(1, 'month').endOf('month').format('DD'))

  const [calendarList, setCalenderList] = useState([]);

  const firstUpdate = useRef(true);

  useEffect(() => {
    if(daysInMon){
      setCalenderList(e => {
        let copy = new Array(daysInMon).fill('');
        for(let i = 0;i<copy.length;i++){
          copy[i] = {value:i+1};
        }
        copy.splice(0,0,...new Array(startWeekDay).fill(''))
        /*一共42个格子*/
        let last = 42 - copy.length;
        if(copy.length !== 42 || copy[0] === ''){
          if(startWeekDay !== 0){
            /*塞入上个月的号*/
            for(let i = startWeekDay - 1;i>=0;i--){
              copy[i] = {value:parseInt(lastMonthDay)-(startWeekDay-i - 1), isGray:true};
            }
          }
          /*塞入下个月的号*/
          for(let i = 0;i < last;i++){
            copy.push({value:i+1, isGray: true});
          }
        }
        return copy
      })
    }else{
      setDaysInMonth(e => {
        let copy = e
        copy = moment(new Date(`${curYear}-${curMonth}`), "YYYY-MM").daysInMonth()
        return copy
      })
    }
  }, [daysInMon])

  useEffect(() => {
    if(firstUpdate.current){
      firstUpdate.current = false;
      return;
    }else{
      /*每次改变计算当前选择年月的日,先设置null防止值一样不触发*/
      setCurDay(null)
      setStartWeekDay(compStartWeekDayIndex)
      if(curMonth === 1){
        setLastMonthDay(moment(new Date(`${curYear-1}-${curMonth}`)).subtract(1, 'days').endOf('month').format('DD'))
      }else if(`${defaultCurYear}-${defaultCurMonth}` === `${curYear}-${curMonth}`){
        setLastMonthDay(moment(new Date(`${curYear}-${curMonth}`)).subtract(1, 'days').endOf('month').format('DD'))
      }else{
        setLastMonthDay(moment(new Date(`${curYear}-${curMonth}`)).subtract(1, 'days').endOf('month').format('DD'))
      }
    }
  },[curMonth])

  useEffect(() => {
    if(firstUpdate.current){
      firstUpdate.current = false;
      return;
    }else{
      /*判断防止副作用依赖值一样不触发*/
      if(!curDay){
        /*计算是否是当年当月当日赋予当天的样式*/
        if(`${defaultCurYear}-${defaultCurMonth}` === `${curYear}-${curMonth}`){
          setCurDay(defaultCurDay)
        }else{
          setCurDay(moment(new Date(`${curYear}-${curMonth}`), "YYYY-MM").daysInMonth())
        }
        setDaysInMonth(null);
      }
    }
  }, [curDay])

  function compStartWeekDayIndex(){
    /*周六为6,周日为0*/
    let timeCode = moment(new Date(`${curYear}-${curMonth}`)).startOf('month').day();
    if(timeCode === 0){
      return 6;
    }else{
      return timeCode - 1;
    }
  }

  function isCurDay(i){
    if(curDate === moment(new Date(`${curYear}-${curMonth}-${curDay}`)).format('YYYY-MM-DD') && defaultCurDay === calendarList[i].value && !calendarList[i].isGray){
      return true
    }else{
      return false
    }
  }

  function prev(){
    if(curMonth === 1){
      setCurYear(e => {
        let copy = curYear;
        copy -= 1
        return copy;
      })
      setCurMonth(12)
    }else{
      setCurMonth(e => {
        let copy = curMonth
        copy -= 1
        return copy;
      })
    }
  }

  function next(){
    if(curMonth === 12){
      setCurYear(e => {
        let copy = curYear;
        copy += 1
        return copy;
      })
      setCurMonth(1)
    }else{
      setCurMonth(e => {
        let copy = curMonth
        copy += 1
        return copy;
      })
    }
  }

  return (
    <div className={'w-full p-4 bg-white rounded-md bg-opacity-50 hover:bg-opacity-100 transition duration-200 mb-4 dark:bg-dark dark:hover:bg-darkHover'}>
      <div className={'flex'}>
        <button className={'flex-none w-10 h-10 bg-gray-300 rounded transition duration-200 dark:bg-black dark:bg-opacity-75 dark:text-white'} onClick={prev}><i className={'iconfont'}>&#xe6e9;</i></button>
        <div className={'flex-grow h-10 text-center leading-10 text-gray-600 dark:text-white'}>{`${curYear}${curMonth}${curDay}`}</div>
        <button className={'flex-none w-10 h-10 bg-gray-300 rounded transition duration-200 dark:bg-black dark:bg-opacity-75 dark:text-white'} onClick={next}><i className={'iconfont'}>&#xe6ee;</i></button>
      </div>
      <ul className={'grid grid-cols-7 grid-flow-row text-gray-600 dark:text-white'}>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
        <li className={'text-center h-10 leading-10'}></li>
      </ul>
      <ul className={'grid grid-cols-7 grid-rows-6 grid-flow-row'}>
        {
          calendarList.map((item,index) => {
            return(
              <li
                key={index}
                className={`text-center h-10 leading-10 ${isCurDay(index) ? 'bg-gray-300 rounded-full dark:bg-black dark:bg-opacity-75' : ''}`}
              >
                <span className={`${item.isGray ? 'text-gray-300 dark:text-gray-900' : 'text-gray-500 dark:text-white'}`}>{item.value}</span>
              </li>
            )
          })
        }
      </ul>
    </div>
  )

样式使用了tailwind.css 需要自己安装或者按自己风格改样式。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:TW
链接:http://www.lucklytw.cn/detail/2
来源:lucklytw.cn 著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值