Taro打卡日历组件。支持h5、ReactNative、后续支持小程序

效果图
在这里插入图片描述
父组件需要传的值

            dateDesc:{
                year:2020,  //年份
                month:7,    //月分传人0默认为当前月份
                list:[
                    1,2,3,5,7,8,12,30,23,18	//默认选中的日期
                ]
            }
            
    changeModal(){  //控制模态框的显隐
        this.setState({
            isShowModal:false
        })
    }
   //应用日历组件         
     <Calendar list={dateDesc.list}></Calendar>
     {!!isShowModal && (	//模态框组件
         <DaKaModalBox parent={this}></DaKaModalBox>
     )}

Calendar组件

import Taro, { Component } from '@tarojs/taro'
import { View, Text,Image } from '@tarojs/components'
import styles from './calendar.scss'
import {getDateNum,getNewMonth,numConvCh,getNewYear,getDate} from '../../../commons/date'

//申明props类型
type PropsType = {
    year:number,  //年份
    month:number,    //月分传人0默认为当前月份
    list:Array<number>  //打过卡的日期
}
//申明state类型
type StateType = {
    month:number,    //当前的月份
    weekList:Array<String>,
    dayNum:Array<number>,  //这个月有多少天
    weekday:number,  //今天是星期几  0周日,1周一
}
//申明接口
interface Calendar{
    props:PropsType,
    state:StateType
}
class Calendar extends Component{
    constructor(props:any){
        super(props)
        this.state = {
            month:0,    //当前的月份
            weekList:["日","一","二","三","四","五","六"],
            dayNum:[],  //这个月有多少天
            weekday:0,  //今天是星期几  0周日,1周一
        }
    }
    static defaultProps = { //默认设置只对undefined有用
        year:getNewYear(),
        month:getNewMonth(),
        list:[]
    }

    componentWillMount(){   //初始化完成
        console.log(this.props)
        let month = numConvCh(this.props.month)
        //获取某个月第一天是星期几
        let day = new Date(String(this.props.month) + "/1/" + String(this.props.year)).getDay()
        this.setState({
            month:month,
            dayNum:this.getDayList(getDateNum(this.props.month,this.props.year)),
            weekday:day
        })
    }
    getDayList(num:number){
        let list:any[] = [];
        //获取某个月第一天是星期几
        let day = new Date(String(this.props.month) + "/1/" + String(this.props.year)).getDay()
        let upDayNum = getDateNum(this.props.month == 1?12:this.props.month - 1,this.props.month == 1?this.props.year -1:this.props.year) //获取上个月有多少天
        let weekDays = ['日','一','二','三','四','五','六']
        for(var i = 0;i < weekDays.length;i++){ //推入星期几
            list.push(weekDays[i])
        }
        while(day > 0){
            day--;
            list.push(upDayNum-day);
        }
        for(let i = 1;i <= num;i++){    //推入这个月的天数
            list.push(i)
        }
        if(list.length%7!=0){   //补齐剩下的格子
            let num = 7 - list.length%7;
            for(let i = 0;i<num;i++){
                list.push("")
            }
        }
        return list
    }

    render(){
        const {
            month:month,
            dayNum:dayNum,
            weekday:weekday
        } = this.state
        const {
            list:list
        } = this.props
        return(
            <View className={styles.calendarBox} style={styles.calendarBox}>
                <View className={styles.TextBox} style={styles.TextBox}>
                    <Text className={styles.topText} style={styles.topText}>打卡日历</Text>
                    <Text className={styles.botText} style={styles.botText}>({month}月)</Text>
                </View>
                <View className={styles.contentBox} style={styles.contentBox}>
                    <View className={styles.dateListBox} style={styles.dateListBox}>
                        <View className={styles.dateList} style={styles.dateList}>
                            {
                                dayNum.map((item:number,index:number)=>{
                                    return(
                                        <View 
                                        className={(list.indexOf(item) > -1 && index >= weekday+7)?[styles.dateListItem,styles.hoverdateListItem]:(index<7?styles.dateListItemNone:styles.dateListItem)} 
                                        style={process.env.TARO_ENV === 'rn'?(list.indexOf(item) > -1 && index >= weekday+7)?[styles.dateListItem,styles.hoverdateListItem]:(index<7?styles.dateListItemNone:styles.dateListItem):""}
                                        key={index}>
                                            <Text className={styles.dataListText} style={styles.dataListText}>{item}</Text>
                                            {
                                                (list.indexOf(item) > -1 && index >= weekday+7)?<View className={styles.IconBox} style={styles.IconBox}>
                                                            <Image className={styles.iconImg} style={styles.iconImg} src={require("./../../../assets/icon/dakachenggong.png")}></Image>
                                                        </View>
                                                    :<View></View>
                                            }
                                        </View>
                                    )
                                })
                            }
                        </View>
                    </View>
                </View>
            </View>
        )
    }
}
export default Calendar

Calendar组件样式

@mixin border($position, $width, $style, $color) {
    /* #ifndef rn */    //不知道为什么不生效
    // #{border-#{$position}}: $width $style $color;
    /* #endif */
    /*#ifndef RN*/
    border: 0 $style $color;
    @each $d in $position {
      #{border-#{$d}-width}: $width;
    }
    /*#endif*/
}
@mixin border2($position, $width, $style, $color) {  //h5中:border: 0 $style $color会清除上一个border
    @each $d in $position {
      #{border-#{$d}-width}: $width;
    }
}
.calendarBox{
    margin-top: 60px;
}
.TextBox{
    display: flex;
    flex-direction: column;
}
.topText{
    font-family: PingFangSC-Medium;
    font-size: 70px;
    color: #343434;
    text-align: center;
    line-height: 102px;
}
.botText{
    font-family: PingFangSC-Medium;
    font-size: 54px;
    color: #161616;
    text-align: center;
    line-height: 102px;
}
.contentBox{
    padding-left: 40px;
    padding-right: 38px;
}
.dateListBox{
    width: 998px;
    overflow: hidden;
}
.dateList{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    overflow: hidden;
    width: 1002px;
    margin-left: -2px;
}
.dateListItem{
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 140px;
    height: 174px;
    @include border(left,2px,solid,#979797);
    @include border2(top,2px ,solid , #979797)
}
.dateListItemNone{
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 140px;
    @include border(right,2px,solid,#fff);
    height: 122px;
}
.hoverdateListItem{
    background-color: #EDFAFE;
}
.dataListText{
    margin-top: 26px;
    font-family: PingFangSC-Regular;
    font-size: 42px;
    color: #ABABAB;
    text-align: center;
}
.IconBox{
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
}
.iconImg{
    margin-top: 13px;
    width: 50px;
    height: 40px;
}

//遮罩层组件

import Taro, { Component } from '@tarojs/taro'
import { View, Text,Image } from '@tarojs/components'
import styles from './daKaModalBox.scss'
import ButtonBox from './../utils/buttonBox'

type PropsType = {
    parent:Object
}
type StateType = {
    
}
interface DaKaModalBox{
    props:PropsType
}

class DaKaModalBox extends Component{
    constructor(props:any){
        super(props)
        this.state = {
            
        }
    }

    isDaKa(year:number,month:number,list:Array<number>){   //判断今天有没有打卡 参数list打卡列表
        if(year == getNewYear() && month == month){   //判断传入年月是否为当前月份
            if(list.indexOf(getDate()) == -1){  //没有打卡的话进行打卡操作
                // this.
            }
        }
    }
    render(){
        return(
            <View className={styles.modalBox} style={styles.modalBox}>
                <View className={styles.modalBoxSM} style={styles.modalBoxSM}>
                    {!!this.props && (
                        <Image className={styles.backImg} style={styles.backImg} src={require('./../../../assets/icon/tanchuang.png')}></Image>
                    )}
                    <View className={styles.modalBoxTextBox} style={styles.modalBoxTextBox}>
                        <Text className={styles.modalBoxDKCG} style={styles.modalBoxDKCG}>打卡成功</Text>
                        <Image className={styles.modalBoxTextDKIcon} style={styles.modalBoxTextDKIcon} src={require('./../../../assets/icon/daka2.png')}></Image>
                        <Text className={styles.modalBoxTextDK} style={styles.modalBoxTextDK}>打卡</Text>
                        <Text className={styles.modalBoxTextLX} style={styles.modalBoxTextLX}>您已连续打卡5天</Text>
                        <Image className={styles.modalBoxBorder} style={styles.modalBoxBorder} src={require('../../../assets/icon/Group14Copy.png')}></Image>
                        <View className={styles.modalBoxBtnBox} style={styles.modalBoxBtnBox}>
                            <ButtonBox onEvent={()=>this.props.parent.changeModal()}>
                                <Image className={styles.modalBoxBtnIcon} style={styles.modalBoxBtnIcon} src={require('./../../../assets/icon/anniu.png')}></Image>
                                <Text className={styles.modalBoxBtn} style={styles.modalBoxBtn}>知道了</Text>
                            </ButtonBox>
                        </View>
                    </View>
                </View>
            </View>
        )
    }
}
export default DaKaModalBox;

遮罩层样式

.modalBox{
    position: absolute;
    top: 0px;
    left: 0px;
    width: 1082px;
    height: 100%;
    background-color: rgba($color: #000000, $alpha: .2);
    display: flex;
    flex-direction: row;
    justify-content: center;
    z-index: 1;
}
.modalBoxSM{
    position: relative;
    width: 100%;
    height: 100%;
}
.backImg{
    position: absolute;
    width: 840px;
    height: 816px;
    top: 0;
    left: 0;
    top: 490px;
    left: 50%;
    margin-left: -406px;
    z-index: 1;
}
.modalBoxTextBox{
    position: absolute;
    width: 840px;
    height: 816px;
    top: 0;
    left: 0;
    top: 490px;
    left: 50%;
    margin-left: -406px;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.modalBoxDKCG{
    margin-top: 44px;
    margin-bottom: 28px;
    font-size: 84px;
    color: #FE890D;
    height: 118px;
    line-height: 118px;
}
.modalBoxTextDK{
    font-size: 44px;
    color: #64ACFF;
    height: 62px;
    line-height: 62px;
    margin-top: 58px;
}
.modalBoxTextLX{
    font-size: 60px;
    color: #343434;
    height: 84px;
    line-height: 84px;
    margin-top: 114px;
}
.modalBoxBorder{
    width: 716px;
    margin-top: 96px;
    height: 2px;
}
.modalBoxTextDKIcon{
    position: absolute;
    top: 190px;
    left: 294px;
    width: 268px;
    height: 144px;
    z-index: -1;
}
.modalBoxBtnBox{
    width: 100%;
    padding-top: 54px;
    position: relative;
    text-align: center;
    display: flex;
    flex-direction: row;
    justify-content: center;
}
.modalBoxBtnIcon{
    position: absolute;
    width: 280px;
    height: 100px;
    left: 50%;
    top: 50%;
    margin-left: -145px;
    margin-top: -20px;
    /* #ifdef rn */    //不知道为什么不生效
    margin-top: -50px;
    /* #endif */
    z-index: -1;
}
.modalBoxBtn{
    font-size: 40px;
    color: #9A6A01;
    height: 56px;
    line-height: 56px;
}

//ButtonBox是我自己定义的一个按钮、仅仅是为了在ReactNative使用TouchableOpacity

import Taro, { Component } from '@tarojs/taro'
import { View,Text } from '@tarojs/components'
import ButtonRn from './../../../reactNative/components/buttonBox'


class ButtonBox extends Component<any,any>{
    constructor(props:any){
        super(props)
        this.state = {

        }
    }
    render(){
        return(
            <View>
                {process.env.TARO_ENV === 'rn'?
                <ButtonRn onEvent={this.props.onEvent}>
                    {this.props.children}
                </ButtonRn>:
                <View onClick={this.props.onEvent}>
                    {this.props.children}
                </View>
                }
            </View>
        )
    }
}
export default ButtonBox

ReactNative中的Button按钮:

import {TouchableOpacity} from 'react-native'
import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'

class buttonRN extends Component<any,any>{
    constructor(props:any){
        super(props)
        this.state = {

        }
    }

    render(){
        return(
            <View>
                <TouchableOpacity onPress={()=>this.props.onEvent()}>{this.props.children}</TouchableOpacity>
            </View>
        )
    }
}
export default buttonRN

写的比较粗糙、有错误欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值