成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

手把手教會(huì)使用react開(kāi)發(fā)日歷組件

lingdududu / 3212人閱讀

摘要:你也可以從其他星期開(kāi)始,不過(guò)會(huì)對(duì)下面的日期顯示有影響,因?yàn)槊總€(gè)月的第一天是周幾決定第一天顯示在第幾個(gè)格子里。首先要根據(jù)年月的第一天獲得,根據(jù)這個(gè)獲取周幾。

準(zhǔn)備工作

提前需要準(zhǔn)備好react腳手架開(kāi)發(fā)環(huán)境,由于react已經(jīng)不支持在頁(yè)面內(nèi)部通過(guò)jsx.transform來(lái)轉(zhuǎn)義,我們就自己大了個(gè)簡(jiǎn)易的開(kāi)發(fā)環(huán)境

創(chuàng)建一個(gè)文件夾,命名為react-canlendar

cd ./react-canlendar

運(yùn)行

npm init

一路enter我們得到一個(gè)package.json的文件

安裝幾個(gè)我們需要的腳手架依賴包

npm install awesome-typescript-loader typescript webpack webpack-cli -D

安裝幾個(gè)我們需要的類庫(kù)

npm install @types/react react react-dom --save

基礎(chǔ)類庫(kù)安裝完畢,開(kāi)始構(gòu)建webpack配置

新建一個(gè)目錄config,config下面新增一個(gè)文件,名字叫做webpack.js

var path = require("path")

module.exports = {
    entry: {
        main: path.resolve(__dirname, "../src/index.tsx")
    },
    output: {
        filename: "[name].js"
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js", ".json"]
    },
    module: {
        rules: [
            {test: /.tsx?$/, use: ["awesome-typescript-loader"]}
        ]
    }
}

還需要?jiǎng)?chuàng)建一個(gè)index.html文件,這是我們的入口文件




    
    Document


    

以上環(huán)境只是一個(gè)極簡(jiǎn)單的環(huán)境,真實(shí)環(huán)境要比這個(gè)復(fù)雜的多。

好了,言歸正傳,我們還是聚焦到日歷組件的開(kāi)發(fā)中來(lái)吧

創(chuàng)建一個(gè)src文件夾,內(nèi)部創(chuàng)建一個(gè)index.tsx文件。

這個(gè)入口文件很簡(jiǎn)單就是一個(gè)掛載

import * as React from "react"
import * as ReactDOM from "react-dom"

ReactDOM.render((
  
test
), document.getElementById("root"))

ok,打開(kāi)頁(yè)面可以看到頁(yè)面正常顯示了test字樣。

我們需要?jiǎng)?chuàng)建Calendar組件了。

創(chuàng)建一個(gè)components文件夾,內(nèi)部創(chuàng)建一個(gè)Calendar.tsx文件。

import * as React from "react"

export default class Calendar extends React.Component {
  render() {
   
    return (
日歷
) } }

在index.tsx中把Calendar.tsx引入,并使用起來(lái)。于是index.tsx變成這個(gè)樣子。

import * as React from "react"
import * as ReactDOM from "react-dom"
import Calendar from "./components/Calendar"

ReactDOM.render((
  
), document.getElementById("root"))

可以看到頁(yè)面顯示了日歷字樣。

要顯示日歷,首先需要顯示日歷這個(gè)大框以及內(nèi)部的一個(gè)個(gè)小框。實(shí)現(xiàn)這種布局最簡(jiǎn)單的布局就是table了

所以我們首先創(chuàng)建的是這種日歷table小框框,以及表頭的星期排列。

import * as React from "react"

const WEEK_NAMES = ["日", "一", "二", "三", "四", "五", "六"]
const LINES = [1,2,3,4,5,6]

export default class Calendar extends React.Component {
  render() {
    return (
{ WEEK_NAMES.map((week, key) => { return }) } { LINES.map((l, key) => { return { WEEK_NAMES.map((week, index) => { return }) } }) }
{week}
{index}
) } }

可以看到我們使用了一個(gè)星期數(shù)組作為表頭,我們按照慣例是從周日開(kāi)始的。你也可以從其他星期開(kāi)始,不過(guò)會(huì)對(duì)下面的日期顯示有影響,因?yàn)槊總€(gè)月的第一天是周幾決定第一天顯示在第幾個(gè)格子里。

那為什么行數(shù)要6行呢?因?yàn)槲覀兪前凑兆畲笮袛?shù)來(lái)確定表格的行數(shù)的,如果一個(gè)月有31天,而這個(gè)月的第一天剛好是周六。就肯定會(huì)顯示6行了。

為了顯示好看,我直接寫好了樣式放置在index.html中了,這個(gè)不重要,不講解。




    
    Document
    


    

下面就要開(kāi)始顯示日期了,首先要把當(dāng)前月份的日期顯示出來(lái),我們先在組件的state中定義當(dāng)前組件的狀態(tài)

state = {
    month: 0,
    year: 0,
    currentDate: new Date()
}

我們定義一個(gè)方法獲取當(dāng)前年月,為什么不需要獲取日,因?yàn)槿諝v都是按月顯示的。獲取日現(xiàn)在看來(lái)對(duì)我們沒(méi)有意義,于是新增一個(gè)方法,設(shè)置當(dāng)前組件的年月

setCurrentYearMonth(date) {
    var month = Calendar.getMonth(date)
    var year = Calendar.getFullYear(date)
    this.setState({
      month,
      year
    })
}

static getMonth(date: Date): number{
    return date.getMonth()
}

static getFullYear(date: Date): number{
    return date.getFullYear()
}

創(chuàng)建兩個(gè)靜態(tài)方法獲取年月,為什么是靜態(tài)方法,因?yàn)榕c組件的實(shí)例無(wú)關(guān),最好放到靜態(tài)方法上去。

要想繪制一個(gè)月還需要知道一個(gè)月的天數(shù)吧,才好繪制吧

所以我們創(chuàng)建一個(gè)數(shù)組來(lái)表示月份的天數(shù)

const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]  // 暫定2月份28天吧

組件上創(chuàng)建一個(gè)函數(shù),根據(jù)月份獲取天數(shù),也是靜態(tài)的

static getCurrentMonthDays(month: number): number {
    return MONTH_DAYS[month]
}

下面還有一個(gè)重要的事情,就是獲取當(dāng)前月份第一天是周幾,這樣子就可以決定把第一天繪制在哪里了。首先要根據(jù)年月的第一天獲得date,根據(jù)這個(gè)date獲取周幾。

static getDateByYearMonth(year: number, month: number, day: number=1): Date {
    var date = new Date()
    date.setFullYear(year)
    date.setMonth(month, day)
    return date
  }

這里獲得每個(gè)月的第一天是周幾了。

static getWeeksByFirstDay(year: number, month: number): number {
    var date = Calendar.getDateByYearMonth(year, month)
    return date.getDay()
  }

好了,開(kāi)始在框子插入日期數(shù)字了。因?yàn)槊總€(gè)日期都是不一樣的,這個(gè)二維數(shù)組可以先計(jì)算好,或者通過(guò)函數(shù)直接插入到j(luò)sx中間。

static getDayText(line: number, weekIndex: number, weekDay: number, monthDays: number): any {
    var number = line * 7 + weekIndex - weekDay + 1
    if ( number <= 0 || number > monthDays ) {
      return  
    }

    return number
  }

看一下這個(gè)函數(shù)需要幾個(gè)參數(shù)哈,第一個(gè)行數(shù),第二個(gè)列數(shù)(周幾),本月第一天是周幾,本月天數(shù)。line * 7 + weekIndex表示當(dāng)前格子本來(lái)是幾,減去本月第一天星期數(shù)字。為什么+1,因?yàn)樗饕菑?開(kāi)始的,而天數(shù)則是從1開(kāi)始。那么<0 || >本月最大天數(shù)的則過(guò)濾掉,返回一個(gè)空span,只是為了撐開(kāi)td。其他則直接返回?cái)?shù)字。

import * as React from "react"

const WEEK_NAMES = ["日", "一", "二", "三", "四", "五", "六"]
const LINES = [1,2,3,4,5,6]
const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

export default class Calendar extends React.Component {
  state = {
    month: 0,
    year: 0,
    currentDate: new Date()
  }

  componentWillMount() {
    this.setCurrentYearMonth(this.state.currentDate)
  }

  setCurrentYearMonth(date) {
    var month = Calendar.getMonth(date)
    var year = Calendar.getFullYear(date)
    this.setState({
      month,
      year
    })
  }

  static getMonth(date: Date): number{
    return date.getMonth()
  }

  static getFullYear(date: Date): number{
    return date.getFullYear()
  }

  static getCurrentMonthDays(month: number): number {
    return MONTH_DAYS[month]
  }

  static getWeeksByFirstDay(year: number, month: number): number {
    var date = Calendar.getDateByYearMonth(year, month)
    return date.getDay()
  }

  static getDayText(line: number, weekIndex: number, weekDay: number, monthDays: number): any {
    var number = line * 7 + weekIndex - weekDay + 1
    if ( number <= 0 || number > monthDays ) {
      return  
    }

    return number
  }

  static formatNumber(num: number): string {
    var _num = num + 1
    return _num < 10 ? `0${_num}` : `${_num}`
  }

  static getDateByYearMonth(year: number, month: number, day: number=1): Date {
    var date = new Date()
    date.setFullYear(year)
    date.setMonth(month, day)
    return date
  }

  checkToday(line: number, weekIndex: number, weekDay: number, monthDays: number): Boolean {
    var { year, month } = this.state
    var day = Calendar.getDayText(line, weekIndex, weekDay, monthDays)
    var date = new Date()
    var todayYear = date.getFullYear()
    var todayMonth = date.getMonth()
    var todayDay = date.getDate()

    return year === todayYear && month === todayMonth && day === todayDay
  }

  monthChange(monthChanged: number) {
    var { month, year } = this.state
    var monthAfter = month + monthChanged
    var date = Calendar.getDateByYearMonth(year, monthAfter)
    this.setCurrentYearMonth(date)
  }

  render() {
    var { year, month } = this.state
    console.log(this.state)

    var monthDays = Calendar.getCurrentMonthDays(month)
    var weekDay = Calendar.getWeeksByFirstDay(year, month)

    return (
{this.state.month} { WEEK_NAMES.map((week, key) => { return }) } { LINES.map((l, key) => { return { WEEK_NAMES.map((week, index) => { return }) } }) }
< {year} - {Calendar.formatNumber(month)} >
{week}
{Calendar.getDayText(key, index, weekDay, monthDays)}
) } }

可以看到最終的代碼多了一些東西,因?yàn)槲壹恿嗽路莸那袚Q。

還記的上文我們把二月份天數(shù)寫28天嘛?要不你們自己改改,判斷一下閏年。

創(chuàng)建了一個(gè)程序員交流微信群,大家進(jìn)群交流IT技術(shù)

如果已過(guò)期,可以添加博主微信號(hào)15706211347,拉你進(jìn)群

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97510.html

相關(guān)文章

  • 把手教會(huì)使用react開(kāi)發(fā)日歷組件

    摘要:你也可以從其他星期開(kāi)始,不過(guò)會(huì)對(duì)下面的日期顯示有影響,因?yàn)槊總€(gè)月的第一天是周幾決定第一天顯示在第幾個(gè)格子里。首先要根據(jù)年月的第一天獲得,根據(jù)這個(gè)獲取周幾。 準(zhǔn)備工作 提前需要準(zhǔn)備好react腳手架開(kāi)發(fā)環(huán)境,由于react已經(jīng)不支持在頁(yè)面內(nèi)部通過(guò)jsx.transform來(lái)轉(zhuǎn)義,我們就自己大了個(gè)簡(jiǎn)易的開(kāi)發(fā)環(huán)境 創(chuàng)建一個(gè)文件夾,命名為react-canlendar cd ./react-c...

    remcarpediem 評(píng)論0 收藏0
  • redux原來(lái)如此簡(jiǎn)單

    摘要:是狀態(tài)容器,提供可預(yù)測(cè)化的狀態(tài)管理。一般我們會(huì)使用一個(gè)常量來(lái)表示對(duì)應(yīng)的值。作為純函數(shù),內(nèi)部不建議使用任何有副作用的操作,比如操作外部的變量,任何導(dǎo)致相同輸入但輸出卻不一致的操作。結(jié)合,其他類庫(kù),開(kāi)發(fā)步驟莫不如此。 Redux 是 JavaScript 狀態(tài)容器, 提供可預(yù)測(cè)化的狀態(tài)管理。 那什么是可以預(yù)測(cè)化,我的理解就是根據(jù)一個(gè)固定的輸入,必然會(huì)得到一個(gè)固定的結(jié)果。 redux是專門為...

    wuyumin 評(píng)論0 收藏0
  • webpack 教程資源收集

    學(xué)習(xí)的過(guò)程中收藏了這些優(yōu)秀教程和的項(xiàng)目,希望對(duì)你有幫助。 github地址, 有不錯(cuò)的就更新 官方文檔 中文指南 初級(jí)教程 webpack-howto 作者:Pete Hunt Webpack 入門指迷 作者:題葉   webpack-demos 作者:ruanyf 一小時(shí)包教會(huì) —— webpack 入門指南 作者:VaJoy Larn   webpack 入門及實(shí)踐 作者:...

    Backache 評(píng)論0 收藏0
  • 前端窩 - 收藏集 - 掘金

    摘要:毫無(wú)疑問(wèn),設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的設(shè)計(jì)模式使代碼編寫真正工程化設(shè)計(jì)模小書(shū)前端掘金這是一本關(guān)于的小書(shū)。 JavaScript 常見(jiàn)設(shè)計(jì)模式解析 - 掘金設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。毫無(wú)疑問(wèn),設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的;設(shè)計(jì)...

    李文鵬 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<