摘要:你也可以從其他星期開始,不過會對下面的日期顯示有影響,因為每個月的第一天是周幾決定第一天顯示在第幾個格子里。首先要根據年月的第一天獲得,根據這個獲取周幾。
準備工作
提前需要準備好react腳手架開發環境,由于react已經不支持在頁面內部通過jsx.transform來轉義,我們就自己大了個簡易的開發環境
創建一個文件夾,命名為react-canlendar
cd ./react-canlendar
運行
npm init
一路enter我們得到一個package.json的文件
安裝幾個我們需要的腳手架依賴包
npm install awesome-typescript-loader typescript webpack webpack-cli -D
安裝幾個我們需要的類庫
npm install @types/react react react-dom --save
基礎類庫安裝完畢,開始構建webpack配置
新建一個目錄config,config下面新增一個文件,名字叫做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"]} ] } }
還需要創建一個index.html文件,這是我們的入口文件
Document
以上環境只是一個極簡單的環境,真實環境要比這個復雜的多。
好了,言歸正傳,我們還是聚焦到日歷組件的開發中來吧
創建一個src文件夾,內部創建一個index.tsx文件。
這個入口文件很簡單就是一個掛載
import * as React from "react" import * as ReactDOM from "react-dom" ReactDOM.render((test), document.getElementById("root"))
ok,打開頁面可以看到頁面正常顯示了test字樣。
我們需要創建Calendar組件了。
創建一個components文件夾,內部創建一個Calendar.tsx文件。
import * as React from "react" export default class Calendar extends React.Component { render() { return (日歷) } }
在index.tsx中把Calendar.tsx引入,并使用起來。于是index.tsx變成這個樣子。
import * as React from "react" import * as ReactDOM from "react-dom" import Calendar from "./components/Calendar" ReactDOM.render((), document.getElementById("root"))
可以看到頁面顯示了日歷字樣。
要顯示日歷,首先需要顯示日歷這個大框以及內部的一個個小框。實現這種布局最簡單的布局就是table了
所以我們首先創建的是這種日歷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} }) }{ WEEK_NAMES.map((week, index) => { return }) }{index} }) }
可以看到我們使用了一個星期數組作為表頭,我們按照慣例是從周日開始的。你也可以從其他星期開始,不過會對下面的日期顯示有影響,因為每個月的第一天是周幾決定第一天顯示在第幾個格子里。
那為什么行數要6行呢?因為我們是按照最大行數來確定表格的行數的,如果一個月有31天,而這個月的第一天剛好是周六。就肯定會顯示6行了。
為了顯示好看,我直接寫好了樣式放置在index.html中了,這個不重要,不講解。
Document
下面就要開始顯示日期了,首先要把當前月份的日期顯示出來,我們先在組件的state中定義當前組件的狀態
state = { month: 0, year: 0, currentDate: new Date() }
我們定義一個方法獲取當前年月,為什么不需要獲取日,因為日歷都是按月顯示的。獲取日現在看來對我們沒有意義,于是新增一個方法,設置當前組件的年月
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() }
創建兩個靜態方法獲取年月,為什么是靜態方法,因為與組件的實例無關,最好放到靜態方法上去。
要想繪制一個月還需要知道一個月的天數吧,才好繪制吧
所以我們創建一個數組來表示月份的天數
const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] // 暫定2月份28天吧
組件上創建一個函數,根據月份獲取天數,也是靜態的
static getCurrentMonthDays(month: number): number { return MONTH_DAYS[month] }
下面還有一個重要的事情,就是獲取當前月份第一天是周幾,這樣子就可以決定把第一天繪制在哪里了。首先要根據年月的第一天獲得date,根據這個date獲取周幾。
static getDateByYearMonth(year: number, month: number, day: number=1): Date { var date = new Date() date.setFullYear(year) date.setMonth(month, day) return date }
這里獲得每個月的第一天是周幾了。
static getWeeksByFirstDay(year: number, month: number): number { var date = Calendar.getDateByYearMonth(year, month) return date.getDay() }
好了,開始在框子插入日期數字了。因為每個日期都是不一樣的,這個二維數組可以先計算好,或者通過函數直接插入到jsx中間。
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
}
看一下這個函數需要幾個參數哈,第一個行數,第二個列數(周幾),本月第一天是周幾,本月天數。line * 7 + weekIndex表示當前格子本來是幾,減去本月第一天星期數字。為什么+1,因為索引是從0開始的,而天數則是從1開始。那么<0 || >本月最大天數的則過濾掉,返回一個空span,只是為了撐開td。其他則直接返回數字。
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}) } }
< {year} - {Calendar.formatNumber(month)} >{ WEEK_NAMES.map((week, key) => { return { LINES.map((l, key) => { return{week} }) }{ WEEK_NAMES.map((week, index) => { return }) }{Calendar.getDayText(key, index, weekDay, monthDays)} }) }
可以看到最終的代碼多了一些東西,因為我加了月份的切換。
還記的上文我們把二月份天數寫28天嘛?要不你們自己改改,判斷一下閏年。
創建了一個程序員交流微信群,大家進群交流IT技術
如果已過期,可以添加博主微信號15706211347,拉你進群
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97510.html
摘要:你也可以從其他星期開始,不過會對下面的日期顯示有影響,因為每個月的第一天是周幾決定第一天顯示在第幾個格子里。首先要根據年月的第一天獲得,根據這個獲取周幾。 準備工作 提前需要準備好react腳手架開發環境,由于react已經不支持在頁面內部通過jsx.transform來轉義,我們就自己大了個簡易的開發環境 創建一個文件夾,命名為react-canlendar cd ./react-c...
摘要:是狀態容器,提供可預測化的狀態管理。一般我們會使用一個常量來表示對應的值。作為純函數,內部不建議使用任何有副作用的操作,比如操作外部的變量,任何導致相同輸入但輸出卻不一致的操作。結合,其他類庫,開發步驟莫不如此。 Redux 是 JavaScript 狀態容器, 提供可預測化的狀態管理。 那什么是可以預測化,我的理解就是根據一個固定的輸入,必然會得到一個固定的結果。 redux是專門為...
學習的過程中收藏了這些優秀教程和的項目,希望對你有幫助。 github地址, 有不錯的就更新 官方文檔 中文指南 初級教程 webpack-howto 作者:Pete Hunt Webpack 入門指迷 作者:題葉 webpack-demos 作者:ruanyf 一小時包教會 —— webpack 入門指南 作者:VaJoy Larn webpack 入門及實踐 作者:...
摘要:毫無疑問,設計模式于己于他人于系統都是多贏的設計模式使代碼編寫真正工程化設計模小書前端掘金這是一本關于的小書。 JavaScript 常見設計模式解析 - 掘金設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。毫無疑問,設計模式于己于他人于系統都是多贏的;設計...
閱讀 1518·2023-04-25 17:41
閱讀 3040·2021-11-22 15:08
閱讀 842·2021-09-29 09:35
閱讀 1605·2021-09-27 13:35
閱讀 3323·2021-08-31 09:44
閱讀 2716·2019-08-30 13:20
閱讀 1939·2019-08-30 13:00
閱讀 2557·2019-08-26 12:12