< template> < div id= "calendar" > < ! --  年份 月份 -- > < div class = "title" > < div class = "label" > 活动日历< / div> < div class = "total" > 当前活动 { {  list. length } }  场< / div> < / div> < div class = "content" > < ul class = "month" > < ! -- 点击会触发pickpre函数,重新刷新当前日期 @click ( vue v- on: click缩写)  -- > < li class = "arrow" > < span@click= "pickPre(currentYear, currentMonth, 'year')" style= "margin-right: 20px" > ❮❮< / span> < span @click= "pickPre(currentYear, currentMonth, 'month')" > ❮< / span> < / li> < li class = "year-month" > < span class = "choose-year" > { {  currentYear } } 年< / span> < span class = "choose-month" > { {  currentMonth } } 月< / span> < / li> < li class = "arrow" > < span @click= "pickNext(currentYear, currentMonth, 'month')" > ❯< / span> < span@click= "pickNext(currentYear, currentMonth, 'year')" style= "margin-left: 20px" > ❯❯< / span> < / li> < / ul> < ! --  星期 -- > < ul class = "weekdays" > < li> 一< / li> < li> 二< / li> < li> 三< / li> < li> 四< / li> < li> 五< / li> < li> 六< / li> < li> 日< / li> < / ul> < ! --  日期 -- > < ul class = "days" > < ! --  核心 v- for 循环 每一次循环用< li> 标签创建一天 -- > < li v- for = "(item, index) in days"  : key= "index" > < ! -- 本月-- > < ! -- 如果不是本月  改变类名加灰色-- > < spanv- if = "item.month != currentMonth" class = "other-month" @click= "clickOtherItem(item)" > { {  + item. date } } < / span> < ! -- 如果是本月  还需要判断是不是这一天-- > < span v- else > < ! -- 今天  同年同月同日-- > < spanclass = "current-month" @click= "clickItem(item)" : class = "{ 'current-day' : item. day. getFullYear ( )  ==  new  Date ( ) . getFullYear ( )  && item. day. getMonth ( )  ==  new  Date ( ) . getMonth ( )  && item. day. getDate ( )  ==  new  Date ( ) . getDate ( ) , active :  item. value ===  activeTime, 'not-allow' :  ! item. hasActivity, 'has-activity' :  item. hasActivity, } "> { {  + item. date } } < / span> < / span> < / li> < / ul> < / div> < / div> 
< / template> < script> 
export  default  { name :  "" , components :  { } , mixins :  [ ] , props :  { } , computed :  { } , watch :  { } , data ( )  { return  { currentDay :  1 , currentMonth :  1 , currentYear :  1970 , currentWeek :  1 , days :  [ ] , activeTime :  "2023-09-21" , list :  [ "2023-09-20" ,  "2023-09-21" ,  "2023-09-11" ] , } ; } , created ( )  { this . initData ( null ) ; } , mounted ( )  { } , methods :  { clickOtherItem ( item )  { if  ( item. month <  this . currentMonth)  { this . pickPre ( this . currentYear,  this . currentMonth,  "month" ) ; }  else  { this . pickNext ( this . currentYear,  this . currentMonth,  "month" ) ; } } , clickItem ( item )  { if  ( ! item. hasActivity)  return ; this . activeTime =  item. value; } , initData :  function  ( cur )  { var  date; console. log ( cur) ; if  ( cur)  { date =  new  Date ( cur) ; }  else  { var  now =  new  Date ( ) ; var  d =  new  Date ( this . formatDate ( now. getFullYear ( ) ,  now. getMonth ( ) ,  1 ) ) ; d. setDate ( 35 ) ; date =  new  Date ( this . formatDate ( d. getFullYear ( ) ,  d. getMonth ( )  +  1 ,  1 ) ) ; } this . currentDay =  date. getDate ( ) ; this . currentYear =  date. getFullYear ( ) ; this . currentMonth =  date. getMonth ( )  +  1 ; this . currentWeek =  date. getDay ( ) ;  if  ( this . currentWeek ==  0 )  { this . currentWeek =  7 ; } var  str =  this . formatDate ( this . currentYear, this . currentMonth, this . currentDay) ; this . days. length =  0 ; console. log ( this . currentWeek,  "this.currentWeek" ) ; for  ( let  i =  this . currentWeek -  1 ;  i >=  0 ;  i-- )  { const  d =  new  Date ( str) ; d. setDate ( d. getDate ( )  -  i) ; const  day =  d; const  year =  d. getFullYear ( ) ; const  month = d. getMonth ( )  +  1  <  10  ?  ` 0 ${ d. getMonth ( )  +  1 } ` :  d. getMonth ( )  +  1 ; const  date =  d. getDate ( )  <  10  ?  ` 0 ${ d. getDate ( ) } ` :  d. getDate ( ) ; const  value =  ` ${ year} - ${ month} - ${ date} ` ; const  dayobject =  { year, month, date, value, day, } ; this . days. push ( dayobject) ;  } for  ( var  i =  1 ;  i <=  35  -  this . currentWeek;  i++ )  { var  d =  new  Date ( str) ; d. setDate ( d. getDate ( )  +  i) ; const  day =  d; const  year =  d. getFullYear ( ) ; const  month = d. getMonth ( )  +  1  <  10  ?  "0"  +  ( d. getMonth ( )  +  1 )  :  d. getMonth ( )  +  1 ; const  date =  d. getDate ( )  <  10  ?  "0"  +  d. getDate ( )  :  d. getDate ( ) ; const  value =  year +  "-"  +  month +  "-"  +  date; var  dayobject =  { year, month, date, value, day, hasActivity :  false ,  } ; this . days. push ( dayobject) ; } this . days =  this . days. map ( ( item )  =>  { if  ( this . list. indexOf ( item. value)  !==  - 1 )  { this . $set ( item,  "hasActivity" ,  true ) ; } return  item; } ) ; } , pickPre :  function  ( year,  month,  type )  { if  ( type ===  "month" )  { const  preMonth =  month -  1  <=  0  ?  12  :  month -  1 ; const  preYear =  month -  1  <=  0  ?  year -  1  :  year; this . initData ( this . formatDate ( preYear,  preMonth,  1 ) ) ; }  else  { this . initData ( this . formatDate ( year -  1 ,  month,  1 ) ) ; } } , pickNext :  function  ( year,  month,  type )  { if  ( type ===  "month" )  { const  nextMonth =  month +  1  >  12  ?  1  :  month +  1 ; const  nextYear =  month +  1  >  12  ?  year +  1  :  year; this . initData ( this . formatDate ( nextYear,  nextMonth,  1 ) ) ; }  else  { this . initData ( this . formatDate ( year +  1 ,  month,  1 ) ) ; } } , formatDate :  function  ( year,  month,  day )  { var  y =  year; var  m =  month; if  ( m <  10 )  m =  "0"  +  m; var  d =  day; if  ( d <  10 )  d =  "0"  +  d; return  y +  "-"  +  m +  "-"  +  d; } , } , 
} ; 
< / script> 
< style lang= "less"  scoped> 
*  { box- sizing:  border- box; 
} 
ul, 
li { list- style:  none; margin :  0 ; padding :  0 ; 
} 
body { font- family:  Verdana,  sans- serif; background :  #e8f0f3; 
} 
#calendar { width :  440px; height :  400px; display :  flex; flex- direction:  column; padding :  20px; margin :  0  auto; box- shadow:  0  2px 2px 0  rgba ( 0 ,  0 ,  0 ,  0.14 ) ,  0  3px 1px - 2px rgba ( 0 ,  0 ,  0 ,  0.1 ) , 0  1px 5px 0  rgba ( 0 ,  0 ,  0 ,  0.12 ) ; 
} 
. title { height :  28px; margin- bottom:  10px; display :  flex; align- items:  center; justify- content:  space- between; . label { color :  #000 ; font- family:  PingFang SC ; font- size:  16px; font- style:  normal; font- weight:  600 ; } . total { height :  28px; padding :  8px 15px; border- radius:  32px; background :  rgba ( 0 ,  91 ,  255 ,  0.1 ) ; display :  flex; align- items:  center; color :  #005bff; font- family:  PingFang SC ; font- size:  14px; font- style:  normal; font- weight:  400 ; } 
} 
. content { display :  flex; flex :  1 ; height :  0 ; flex- direction:  column; . month { height :  40 . 25px; display :  flex; justify- content:  space- between; padding :  0  10px; align- items:  center; . year- month { color :  rgba ( 0 ,  0 ,  0 ,  0.85 ) ; text- align:  center; font- family:  PingFang SC ; font- size:  16px; font- style:  normal; font- weight:  600 ; . choose- year { margin- right:  12px; } } . arrow { span : hover { cursor :  pointer; color :  #005bff; } } } . weekdays { height :  40 . 25px; display :  flex; li { cursor :  default ; display :  flex; align- items:  center; justify- content:  center; width :  calc ( 100 %  /  7 ) ; height :  40px; color :  rgba ( 0 ,  0 ,  0 ,  0.85 ) ; text- align:  center; font- family:  PingFang SC ; font- size:  14px; font- style:  normal; font- weight:  400 ; } } . days { flex :  1 ; height :  0 ; display :  flex; flex- wrap:  wrap; li { display :  flex; align- items:  center; justify- content:  center; width :  calc ( 100 %  /  7 ) ; height :  40px; color :  rgba ( 0 ,  0 ,  0 ,  0.85 ) ; text- align:  center; font- family:  PingFang SC ; font- size:  14px; font- style:  normal; font- weight:  400 ; span { width :  34px; height :  34px; line- height:  34px; } . has- activity { display :  inline- block; width :  34px; height :  34px; position :  relative; } . current- day { color :  #005bff; } . active { color :  #fff; display :  inline- block; width :  34px; height :  34px; background :  #005bff; border- radius:  50 % ; position :  relative; } . other- month { color :  rgba ( 0 ,  0 ,  0 ,  0.45 ) ; cursor :  default ; } . current- month: hover { width :  34px; height :  34px; display :  inline- block; cursor :  pointer; background :  #f2f2f2; color :  rgba ( 0 ,  0 ,  0 ,  0.85 ) ; border- radius:  50 % ; } . active: hover { cursor :  pointer; color :  #fff; display :  inline- block; width :  34px; height :  34px; background :  #005bff; border- radius:  50 % ; } . not- allow: hover { cursor :  not- allowed; background- color:  white; } . has- activity: : after { content :  "" ; position :  absolute; width :  4px; height :  4px; border- radius:  50 % ; background- color:  #005bff; left :  50 % ; bottom :  2px; margin- left:  - 2px; } . active: : after { content :  "" ; position :  absolute; width :  4px; height :  4px; border- radius:  50 % ; background- color:  white; left :  50 % ; bottom :  2px; margin- left:  - 2px; } } } 
} 
< / style>