react 自定义日历组件
2021-02-24 本文已影响0人
曾经也是个少年
基于hooks开发的自定义日历组件,可以根据自己需要修改;
image.png
index.tsx
import React, { useState } from "react";
import Taro from "@tarojs/taro";
import { View } from "@tarojs/components";
import { AtIcon } from 'taro-ui'
import './index.scss'
/**
* @author wangqiang;
* @create 2021-02-24;
* @update wangqiang(2021-02-24)
* @params searchBar => 搜索参数; => 列表数据
* @description 修改请备注 location-grey
*/
const Main = (props) => {
//每月多少天
let MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const WEEK_NAMES = ['日', '一', '二', '三', '四', '五', '六'];
const LINES = [1, 2, 3, 4, 5, 6];
const [year, setLoinsYear] = useState(0);
const [month, seLoinstMonth] = useState(0);
const [currentDate, setcurrentDate] = useState(new Date());
const [tag, setTag] = useState(false);
//获取当前月份
const getMonth = (date: Date): number => {
return date.getMonth();
}
//获取当前年份
const getFullYear = (date: Date): number => {
// console.log(date.getFullYear())
return date.getFullYear();
}
const getCurrentMonthDays = (month: number, year: number): number => {
let _year = year + currentDate.getFullYear();
if(_year % 100 != 0 && _year % 4 == 0 || _year % 400 == 0){
MONTH_DAYS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
}
return MONTH_DAYS[month]
}
//当前月第一天是周几
const getDateByYearMonth = (year: number, month: number, day: number = 1): Date => {
var date = new Date()
date.setFullYear(year)
date.setMonth(month, day)
return date
}
const getWeeksByFirstDay = (year: number, month: number): number => {
var date = getDateByYearMonth(year, month)
return date.getDay()
}
const getDayText = (line: number, weekIndex: number, weekDay: number, monthDays: number): any => {
var number = line * 7 + weekIndex - weekDay + 1
if (number <= 0 || number > monthDays) {
return <View className="day-c" key={weekIndex}> </View>
}
return <View className="day-c" key={weekIndex}>
<View className="day">{number}</View>
<View className="desc">可约</View>
</View>
}
const setCurrentYearMonth = (date) => {
var month = getMonth(date)
var year = getFullYear(date)
setLoinsYear(year);
seLoinstMonth(month)
setTag(false)
}
const monthChange = (monthChanged: number) => {
if (tag) {
return;
} else {
setTag(true)
}
var monthAfter = month + monthChanged
var date = getDateByYearMonth(year, monthAfter)
setCurrentYearMonth(date)
}
const formatNumber = (num: number): string => {
var _num = num + 1
return _num < 10 ? `0${_num}` : `${_num}`
}
// let monthDays = getCurrentMonthDays(month);
let weekDay = getWeeksByFirstDay(year, month);
let _startX = 0;
return <React.Fragment>
<View className="loins-calendar"
onTouchEnd={(val) => {
if (_startX > val.changedTouches[0]['clientX'] + 30) {
monthChange(1);
}
if (_startX < val.changedTouches[0]['clientX'] - 30) {
monthChange(-1);
}
}} onTouchStart={(val) => {
_startX = val.changedTouches[0]['clientX']
}}
>
<View className="loins-calendar-tabbar">
<View><AtIcon value='chevron-left' size='30' color='#297AF8' onClick={() => {
monthChange(-1);
}}></AtIcon></View>
<View className="loins-calendar-title">{year + currentDate.getFullYear()} 年 {formatNumber(month)}月</View>
<View><AtIcon value='chevron-right' size='30' color='#297AF8' onClick={() => {
monthChange(1);
}}></AtIcon></View>
</View>
{
WEEK_NAMES.map((week, key) => {
return <View className="title-c" key={key}>{week}</View>
})
}
{
LINES.map((l, key) => {
return <View key={key} className="day-content">
{
WEEK_NAMES.map((week, index) => {
return getDayText(key, index, weekDay, getCurrentMonthDays(month, year))
})
}
</View>
})
}
</View>
</React.Fragment>
}
export default Main;
index.scss
.loins-calendar {
background-color: #ffffff;
&-tabbar {
padding: 43px 100px 30px 100px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
&-title {
font-size: 36px;
font-family: Helvetica;
color: #333333;
line-height: 48px;
}
.title-c {
display: inline-block;
width: calc(100% / 7);
text-align: center;
font-size: 30px;
font-weight: 400;
color: #606060;
line-height: 40px;
}
width: 100%;
.day-content {
text-align: center;
.day-c {
display: inline-block;
width: calc(100% / 7);
text-align: center;
margin-bottom: 30px;
.day {
font-size: 32px;
font-weight: 500;
color: #303030;
text-align: center;
}
.desc {
height: 28px;
font-size: 20px;
font-weight: 400;
color: #202020;
text-align: center;
}
}
}
}