iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
自我挑戰組

菜雞們,讓我們一起征服JS及React吧系列 第 29

React菜雞-Day29:React實戰~寫個日曆 part2 - 來搞定日曆的外觀吧!

  • 分享至 

  • xImage
  •  
tags: 鐵人賽 React javascript nodejs

鐵人賽第29天,今天我們要設計日曆的外觀,同時建立一個styales.js來定義componentcss,讓你的外觀帥一波!!
/images/emoticon/emoticon30.gif

先來解析一下我們Layout

  • 拆解日曆的架構,我們會如下設計:

建立styles.js,點綴你的元件

  • 建立styles.js檔案,內容以Object的方式建立各元件的style,再運用export的方式,提供給component的參數style

  • 看到落落長的內容,免驚!其實就是每個元件的css定義!

export const STYLES = {
  WIDTH: "280px", 
  HEIGHT: "280px", 
  ONE_COLUMN_HEIGHT: "40px",

  // FontSize
  FONTSIZE_BASIC:"20px", 
  FONTSIZE_MEDIUM:"25px", 
  FONTSIZE_LARGE:"50px", 

  // color
  WEEKDAY_TEXT_COLOR:"grey",
  DATE_DAT_COLOR:"black"
}

// === calendar-container
export const calendarContainer = {
  width:STYLES.WIDTH, 
  height:STYLES.HEIGHT,
  border: "black solid 1px", 
}

//===  Header  ===
export const headerContainer = {
  width:STYLES.WIDTH, 
  height:STYLES.ONE_COLUMN_HEIGHT,
  // border: "black solid 1px", 
  display:"flex",
}
export const headerMonthYearStyle = {
  width: "80%",
  fontSize:STYLES.FONTSIZE_MEDIUM, 
  margin:"0.2rem 0.4rem", 
}

export const headerButtonStyle = {
  width: "10%",
  fontSize:STYLES.FONTSIZE_BASIC, 
  cursor: "pointer",
  margin:"0.4em", 
}


//===  WeekDay  ===
export const weekDayContainerStyle = {
  width:STYLES.WIDTH, 
  height:STYLES.ONE_COLUMN_HEIGHT, 
  // border: "black solid 1px", 
  display: "flex",
};

export const weekDayStyle = {
  width:"100%",
  fontSize:STYLES.FONTSIZE_BASIC, 
  margin:"0.5rem", 
  color:STYLES.WEEKDAY_TEXT_COLOR 
}

//=== Date Content ===
export const DateContainer = {
  width:STYLES.WIDTH, 
  height:"200px",
  // border: "black solid 1px", 
};

export const aWeekStyle = {
  display: "flex",
};

export const dayStyle = {
  width:"100%",
  fontSize:STYLES.FONTSIZE_BASIC, 
  margin:"0.5rem", 
  color:STYLES.DATE_DAT_COLOR,
  textAlign:"center",
}

Header:

  • 解析Header需求
  • month-year: span, 佔了80%的寬度
  • 左箭頭: span,佔了10%的寬度,有onClick Event可往上個月
  • 右箭頭: span,佔了10%的寬度,有onClick Event可往下個月
// Calendar.js
import * as Styles from "./styles";

//...
function Header(){
  let handleLastMonthEvent = ()=>{
    console.log("click last month")
    return (e)=>{}
  }   
  let handleNextMonthEvent = ()=>{
    console.log("click next month")
    return (e)=>{}
  }

  return (
    <div className="header-container" style={Styles.headerContainer}>
      <span style={Styles.headerMonthYearStyle} className="month-year">{"Month-Year"}</span>
      <span style={Styles.headerButtonStyle} onClick={handleLastMonthEvent}> {"<"} </span>
      <span style={Styles.headerButtonStyle} onClick={handleNextMonthEvent}> {">"} </span>
    </div>
  )
}

//...
export default function Calendar() {
  return (
    <div>
      <h1>{"Calendar Demo"}</h1>
      <div className="calendar-container" style={Styles.calendarContainer}>
        <Header />
      </div>
    </div>
  );
}

Quick-review

  • 點擊箭頭看看,看看console.log是否有印出對應的資訊!

WeekDay

  • 解析WeekDay需求
  • container: div,包裝裡頭的七個span,這裡我們使用flex來為我們做排列!
  • 星期幾: span,內容存放星期的簡寫
// Calendar.js

//...
// Global Vars
const WeekDayNameList = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
//...
function WeekDay() {
  let weekDayList = [];
  return (
      <div style={Styles.weekDayContainerStyle}>
        {
          weekDayList = WeekDayNameList.map((name, idx)=>
          <span className="weekday-name" key={`name-${idx}`}
            style={Styles.weekDayStyle}>
            {name}
          </span>)
        }
      </div>
      );
}

//...

export default function Calendar() {
  return (
    <div>
      <h1>{"Calendar Demo"}</h1>
      <div className="calendar-container" style={Styles.calendarContainer}>
        <Header />
        <WeekDay />
      </div>
    </div>
  );
}

Quick-review

  • 檢查看看每個span是否等分的排列好!

DateContent

  • 還記得昨天我們昨天利用moment.js回傳的當月每週的Array吧!在這裡就要派上用場囉!
  • 解析DateContent需求:
  • aWeek: div,一個conrainer並存放當週的每個span,以flex做排列
  • day: span,文字存放當週的日期
  • DateContainer: ·div,包裝每一週的div
function DateContent(){
  let weekContentList = getWeeksInMonth();
  let result = [];
  return (
    <div className="DateContainer" style={Styles.DateContainer}>
      {
        weekContentList.map((week, wIdx)=>{
          let aWeek = [];
          week.map((day, dIdx)=>
            aWeek.push(<span className="dateContent-day" style={Styles.dayStyle} key={`${day}-${dIdx}`}>{day===0?"":day}</span>))
          result.push(<div className="aweek" style={Styles.aWeekStyle} key={`${week}-${wIdx}`}>{aWeek}</div>);
        })
      }
      {result}
    </div>
    )
}

export default function Calendar() {
  return (
    <div>
      <h1>{"Calendar Demo"}</h1>
      <div className="calendar-container" style={Styles.calendarContainer}>
        <Header />
        <WeekDay />
        <DateContent />
      </div>
    </div>
  );

Quick-review

  • 每個日期都排列整齊,讓人賞心悅目!

結論

  • 鐵人賽第29天,今天我們建立了三個元件,搭配styles.js將日曆的外觀完成,同時也結合了昨天建立的函示getWeeksInMonth來顯示日期,看到成果就是讚!
  • 明天是鐵人賽最後一天了,我們把功能串接起來,就完成了最後的成果囉! 加油! Rock~~~ !!
    /images/emoticon/emoticon62.gif

上一篇
React菜雞-Day28:React實戰~寫個日曆 part1
下一篇
React菜雞-Day30:React實戰~寫個日曆 最終篇 - 賦予日曆靈魂吧!
系列文
菜雞們,讓我們一起征服JS及React吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言