效果图
父组件需要传的值
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
写的比较粗糙、有错误欢迎指出