关于日历:妙记多我的主页升级日历聚合任务待办为你打造个人时间管理系统⏰

咱们应该如何解决“日程”和“待办”的关系?日程和待办的区别与分割从字面意义上来了解,日程是这一天的安顿,待办是须要去实现的事件,日程与待办实质上是一种互相蕴含的关系。将所有事件都视作待办显然是不迷信的,那么如果将所有事件都视作日程呢?把所有的待办都放进日历里,是否可行呢? 咱们应用并沟通了用户一段时间发现: 用户需要:我心愿本人每天可能失去一张大抵的日程表和一张须要实现的待办清单,日程表能够及时揭示我去做必须要做的事件,而在我的工夫空进去的时候,它又可能督促我依据待办事项去做事,在一天完结之后,我能够看到本人的待办都实现了,并且日程表上清晰地记录了这所有。 要达到这个指标,妙记多 Mojidoc 「我的主页」提供了如下三合一: 一个记录待办的工具:妙记多 Mojidoc 待办事项/接力/@ 等性能一个记录日程的工具:妙记多 Mojidoc 「我的主页」主动关联工作和日历(可有可无)一个能同步我的日程并揭示我工夫的工具:妙记多的微信告诉综上所述,咱们须要对日程和待办进行肯定水平的整合,让日程表和待办清单同时工作,起到一种互补的成果。通过一段时间的思考和整顿后,咱们降级改版了「我的主页」,将待办和日程有机联合, 心愿咱们提供的用法能给大家带来一点帮忙。 妙记多 Mojidoc 降级「我的主页」为你打造集体工夫管理系统妙记多 Mojidoc 降级「与我相干」板块为「我的主页」。 「日历组件」 ☎️ 「语音转文字组件」 「我的主页」不便你为任何我的项目自定义工作妙记多 Mojidoc 会主动汇总工作列表,待办事项,@ 告诉,接力等事项,聚合在「我的主页」并通过日历视图主动排版,以自定义您的工作治理以满足任何工作需要。 「我的主页」多种视图自动化关联日程/工作/待办清单团队成员传递接力,我的项目任务分配,都会自动化汇总在「我的主页」,每天查看日历即可可能放弃我的项目失常进行,工作的主动调配。 不同视图展现: 「日历视图」 「看板视图」 「列表视图」 「工作视图」 随时随地治理您的待办事项(多平台疾速同步)从任何中央创立和拜访您的待办事项列表:桌面、手机或web端。多端同步查看待办事项 这样「我的主页」的日历就成为了一个具备准确揭示性能的秘书,它既保留了对日程的揭示性能,又保留了看待办的揭示性能,成为了可执行的蓝图。 如何复盘依照计划表行事一段时间后,关上「我的主页」理论状况可能是这样:理论记录实现状况,更可能无效的治理本人的工夫和晋升效率。 话不多说,赶快来妙记多体验一下~

April 26, 2023 · 1 min · jiezi

关于日历:移动端日历组件设计与实现

前言在大多数的客户端利用中,日期的抉择与操作是一个常见的性能,应用日历组件实现对于这一性能的实现,往往是一个高效的解决方案。对于日历组件的设计与开发,在常见的开源我的项目中,通常有两种设计思路: 横向切换展现,默认渲染单个月份,通过按钮或左右滑动,进行月份切换;纵向切换展现,默认渲染展现多个月份,高低滑动进行月份切换;例如增加 picker 进行视图切换,增加自定义按钮,日期单选/多选,自定义文案,日期范畴限度等等性能,这些根本都是在两种思路的根底上进行的性能扩大。 在日常的利用中,两种形式各有优劣: 横向切换,初始渲染的节点更少,渲染性能更加优异;纵向切换,有更加直观的视觉感触,更良好的交互操作;然而,鱼和熊掌不可兼得,交互体验与性能上的取舍,是一个始终都要直面的问题。随着挪动端设施的一直倒退,挪动端浏览器一直的欠缺,用户设施在兼容性与运行效率上都有显著晋升,因而,本文次要论述的,是以竖向切换形式实现的 NutUI Calendar 日历组件。 主题介绍明天的主题是 NutUI Calendar 组件的设计与实现,Calendar 组件是 NutUI 的一个日历组件,它用认为用户提供一个直观的日期抉择形式,以滑动的形式切换月份,反对单个日期与日期范畴的抉择,反对自定义日期内容等性能。明天,让咱们一起来看看,在组件的开发过程中,是如何一步步实现组件性能的。 组件设计思路日历组件,不论以何种形式设计交互,日期工夫数据的解决都是必不可少的,毕竟视图也是为数据信息服务的。在本文中采取的竖向切换展现的形式,也意味着咱们要在节点的渲染性能上做一些优化调整。所以咱们的实现思路次要有以下几点: 日期数据处理,一次性初始化原始数据,在可视区域内,分段渲染节点元素。利用虚构列表的形式,缩小节点元素的渲染开销滚动事件与边界条件的解决功能完善,丰盛 Slots,Props,Events 事件等,晋升扩展性组件的实现原理基本参数需要在解决日期数据时,咱们须要先明确咱们所需的根本工夫入参,例如:日历组件的可选工夫范畴,以后选中的工夫。 通过对传入参数的解析解决,失去咱们所需的数据内容,在之后的开发过程中,实现组件内容的渲染与事件处理。 这里我画了一张图不便大家更好了解: 原始日期数据:是咱们依据日期范畴计算的原始数据以后选中日期:可视范畴的展现以后月份,须要判断选中日期是否在日期范畴内展现范畴区间:依据以后选中日期解决得出,为以后须要渲染的数据范畴容器尺寸信息:用以计算日期滚动切换时的位移信息日期数据处理日期数据的计算,须要有多个处理过程。首先,咱们须要先计算传入的日期范畴是否存在,如果不存在,默认应用最近一年的工夫范畴。之后计算存在多少个月。在依据月的数量去遍历生成日期数据。 在计算单个月日期时,每个月的第一天与最初一天的星期数是不同的,咱们须要依据不同的星期数,以前一个月与后一个月的日期进行补全。这样既能够省去计算 1 号开始地位偏移量,也能够为性能扩大做出铺垫。 // 获取单个月的日期与状态const getDaysStatus = (currMonthDays: number, dateInfo: any) => { let { year, month } = dateInfo; return Array.from(Array(currMonthDays), (v, k) => { return { day: k + 1, type: "curr", year, month, }; }); // 获取上一个月的最初一周天数,填充当月空白 const getPreDaysStatus = ( preCurrMonthDays: number weekNum: number, dateInfo: any, ) => { let { year, month } = dateInfo; if ( weekNum >= 7) { weekNum -= 7; } let months = Array.from(Array(preCurrMonthDays), (v, k) => { return { day: k + 1, type: "prev", year, month, }; }); return months.slice(preCurrMonthDays - weekNum); };};复制代码解决后的数据如下: ...

April 18, 2022 · 3 min · jiezi

关于日历:vika维格表9月更新日历视图神奇关联操作体验优化用心在细节

如果说vika维格表的 8 月版本更新是满满干货,9 月则是精密打磨,用心制作,像谋求完美主义的处女座。 魔鬼藏在细节里,vika维格表 9 月版本更新中,处处都是细节功夫。不信,你看看都更新了些什么: 更新一览: 企业微信集成上线神奇关联显示文案优化,关联记录可高低翻页日历视图挪动端适配侧边栏「帮忙」入口显示成果优化附件维格列优化:在附件停留后显示名称,反对 MP4 视频在窗口内旋转Q4 更新预报:反对中英语言切换、V 币反对兑换、维格社区行将凋谢一、第三方利用集成之企业微信上线在维格表工作告诉揭示的文章中,曾经预报了vika维格表的第三方集成-企业微信行将上线,这次真的来啦。 点击「开明应用」,按操作疏导创立自建利用后,绑定空间。 你的企业就能够在企业微信上: 免登录,间接在企业微信进入维格表空间站,拜访空间站数据通过企业微信接管空间站内告诉在企业微信设置利用可见范畴,并同步企业微信的通讯录 如果还想要更粗疏到某个群的定时、定制告诉,能够戳 这里 看看如何用维格表做企业微信群告诉揭示~ 二、神奇关联细节优化:形容更清晰、多个关联记录能够高低查看神奇关联作为vika维格表的招牌性能,始终在被继续地、精心地打磨,而这次的更新你会感知显著: 开展神奇关联卡片,你能够看到右上角的「返回源表」清晰提醒: 如果某一维格行有多个关联表,能够通过右上角的「↑」「↓」箭头,翻动查看数据。 举个例子:在客户关系治理中,某一业务人员同时对接了多个客户,能够在成员列表中,间接查看 Ta 所有的客户名单以及商机详情。 三、日历视图挪动端优化如果你曾经开始应用维格表的日历视图管理工作工作或排期,会感触到工作清晰、工夫明确的益处,那还想更进一步吗? 更加高效不便的合作答案是:随时随地查看日程工作。 在 9 月版本更新中,日历视图对挪动端进行了适配,反对挪动端查看日历视图并新建记录。 还有一个小小的优化,维卡比猜你应该不会发现:日历视图新增了一个镜像版的 icon。 优化其实不值一提,但维格表是真的在用心做每一处细节的诚意心愿你能懂。 四、多处应用体验优化(1)「帮忙」入口调整为左右布局侧边栏的「帮忙」入口就像维格表的百宝锦囊,你能够随时直通疾速教程、产品路线图、维格课堂、产品手册或是常见问题,为了更加简洁清晰的展现成果,「帮忙」优化为左右布局,一眼就能找到你想要的入口。 (2)附件维格列优化第一弹:鼠标停留将会显示附件名称对于常常须要治理多个图片、合同、文档等附件的同学来说,这次更新的附件名称显示不要太贴心~不必关上预览就能找到本人想要的那一份文件。 只须要鼠标稍作停留,就能看到名称啦。 (3)附件维格列优化第二弹:MP4 视频能够旋转了很多人会在维格表挪动端上传视频,比方拍摄线下流动视频、客户访问实录等等,但协同的懊恼是:上传的视频不肯定适宜 PC 端的观看体验。碰上个不省心的共事,可不把你逼成歪脖君。 为了解放你的脖子,维格表为 MP4 视频新增了旋转按钮,反对视频窗口旋转。 当初,你能在维格表内用更多姿态、更舒服地看视频啦。 (4)新增行的文字揭示维格视图的底部「+」栏呈现了「新增一行」的文字揭示。别再做不小心新增空行的职场萌新啦。 五、精彩预报(1)中英语言切换在凋谢海内手机号注册后,英语界面的维格表也行将上线。与海内共事的合作体验,能够说是亲密无间了~ (2)V 币兑换行将凋谢9 月 1 日后,如果你还没有查看过本人的 V 币余额,快去「我的」查看账户钱包吧,你可能曾经是维格表的「百万小户」啦。 在不久后,V 币将能够兑换白银空间等订阅服务和好礼,一起期待下吧~ (3)维格社区你有没有好奇过,到底是谁和我一样在应用vika维格表呢?他们在用维格表做什么呢? 能够留言、互动、交友的维格社区行将上线,2021 年还没有实现的「结识行业大佬的集体 KPI」,就在维格社区搞定吧~ 对本次性能更新有任何疑难能够留言通知咱们~ ...

October 8, 2021 · 1 min · jiezi

关于日历:实现一个简单的日历输入组件

日历组件 日历组件在平时我的项目中是十分常见的一个组件,那么咱们就来实现一下。实现之前要晓得有哪几个须要留神的点。-一、日期要怎么显示?每个月须要展现不同的日期,那么咱们就来找找法则吧。1.每个月须要展现固定的42天。2.每个月的一号是周几,比方上图中的一号是周二,那么咱们能够应用工夫的getDay函数获取一号的是2,而后让第一天往前推2天,就是咱们须要展现在日历上的第一天了。 二、日期框里的年月不能依据输入框里的日期变动,因为前面还会波及到切换问题三、每次切换都要更新日历板中的日期,使其与对应月份展现的雷同四、每次点击日历中的日期须要暗藏日历板(点击切换年月按钮不暗藏)五、点击日历板上的日期之后再次点击输入框会展现对应月份对应工夫,对应工夫须要给一个非凡展现(如上图蓝色局部)六、不是当月的工夫须要和以后月的日期有辨别(色彩辨别)七、选中了某一天须要更新父组件中的数据八、输入框中录入年月日,点击enter键,再次点击input会弹出对应的日期并且标蓝色下面就是封装这个日历所须要留神到的点,那么上面看代码吧; 代码实现父组件<template> <div id="datePicker"> <Calendar :time="time" v-model="time"></Calendar> <div style="display: inline-block">{{time}}</div> </div></template><script> import Calendar from '../components/calendar'; export default { name: 'datePicker', components: { Calendar }, data() { return { time: new Date() }; }, methods: {} };</script><style></style>子组件 <template> <div id="calendar" v-click-outside> <input type="text" ref="input" class="input" :value="formatterTime" @focus="handlClick" @keydown="enterInput"> <div class="content" v-if="isShow"> <div class="title"> <div class="oper"> <span class="iconfont icon-shuangjiantouzuo" @click="handlChangeDate('year',-1)"></span> <span class="iconfont icon-zuojiantou" @click="handlChangeDate('month',-1)"></span> </div> <div class="date">{{`${timeCopy.year}年${timeCopy.month}月`}}</div> <div class="oper"> <span class="iconfont icon-youjiantou" @click="handlChangeDate('month',+1)"></span> <span class="iconfont icon-shuangjiantouyou" @click="handlChangeDate('year',+1)"></span> </div> </div> <div class="week"> <span class="week-item" v-for="(v,i) in weekList" :key="i">{{v}}</span> </div> <ul class="days"> <li class="days-row" v-for="(v,i) in 6" :key="i"> <span class="days-item" v-for="(vs,j) in 7" :key="j" @click="chooseDay(getCurrentMonthDays[i*7+j])" :class="[ {'gray-day':getCurrentMonthDays[i*7+j].getMonth()+1!=timeCopy.month}, {'high-light':getCurrentMonthDays[i*7+j].getDate()==timeCopy.day} ]" > {{getCurrentMonthDays[i*7+j].getDate()}} </span> </li> </ul> </div> </div></template><script> export default { name: 'calendar', props: { time: {type: Date} }, directives: { 'clickOutside': { bind(el, builing, vNode) { let handler = (e) => { let input = document.getElementsByClassName('input')[0]; let title = document.getElementsByClassName('title')[0]; if (!title) return; if (!input.contains(e.target) && !title.contains(e.target)) { vNode.context.isShow = false; } }; document.addEventListener('click', handler); } } }, computed: { formatterTime() { let {year, month, day} = this.timeCopy; return `${year}-${month}-${day}`; }, getCurrentMonthDays() { let {year, month} = this.timeCopy; let firstDay = new Date(`${year}-${month}-01`); let week = firstDay.getDay(); let beginDay; if (week === 0) { beginDay = firstDay - 7 * 1000 * 60 * 60 * 24; } else { beginDay = firstDay - week * 1000 * 60 * 60 * 24; } let dateArr = []; for (let i = 0; i < 42; i++) { dateArr.push(new Date(beginDay + i * 1000 * 60 * 60 * 24)); } return dateArr; } }, data() { return { isShow: false, timeCopy: {}, weekList: ['日', '一', '二', '三', '四', '五', '六'] }; }, methods: { enterInput(e) { if (e.keyCode == '13') { let val = e.srcElement.value; let {month, day} = this.setData(new Date(val)); if (isNaN(month) || isNaN(day)) { alert('输出不非法哦'); return; } this.timeCopy = this.setData(new Date(e.srcElement.value)); this.$emit('input', new Date(e.srcElement.value)); this.isShow = false; this.$refs.input.blur(); } }, handlChangeDate(flag, val) { this.timeCopy[flag] += val; if (this.timeCopy.month > 12) { this.timeCopy.month = 1; this.timeCopy.year += 1; } if (this.timeCopy.month < 1) { this.timeCopy.month = 12; this.timeCopy.year -= 1; } }, chooseDay(date) { this.$emit('input', date); this.timeCopy = this.setData(date); }, setData(time) { let year = time.getFullYear(); let month = time.getMonth() + 1; let day = time.getDate(); return {year, month, day}; }, handlClick() { this.isShow = true; } }, created() { this.timeCopy = this.setData(this.time); } };</script><style lang="less" scoped> * { margin: 0; padding: 0; } ul li { list-style: none; } #calendar { @commonColor: #00a0ff; text-align: center; display: inline-block; input { width: 268px; background-color: #fff; border-radius: 4px; border: 1px solid #dcdfe6; color: #606266; height: 40px; line-height: 40px; outline: none; padding: 0 15px; } .content { user-select: none; position: absolute; width: 300px; z-index: 100; background: #fff; color: #606266; border: 1px solid #e4e7ed; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1); border-radius: 4px; line-height: 30px; margin: 5px 0; .title { display: flex; height: 25px; line-height: 25px; margin-bottom: 15px; .oper { font-size: 16px; cursor: pointer; flex: 1; } .date { flex: 1; } } .week { display: flex; border-bottom: 1px solid #bfc4cc; .week-item { flex: 1; font-size: 14px; } } .days { display: flex; flex-direction: column; padding: 5px; font-size: 12px; justify-content: space-evenly; .days-row { display: flex; .days-item { flex: 1; cursor: pointer; &:hover { color: @commonColor; } } } } } .gray-day { color: #bfc4cc !important; } .high-light { color: @commonColor; } }</style>

January 5, 2021 · 3 min · jiezi

手把手教会使用react开发日历组件

准备工作提前需要准备好react脚手架开发环境,由于react已经不支持在页面内部通过jsx.transform来转义,我们就自己大了个简易的开发环境创建一个文件夹,命名为react-canlendarcd ./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.jsvar 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文件,这是我们的入口文件<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Document</title></head><body> <div id=“root”></div> <script src="./dist/main.js"></script></body></html>以上环境只是一个极简单的环境,真实环境要比这个复杂的多。好了,言归正传,我们还是聚焦到日历组件的开发中来吧创建一个src文件夹,内部创建一个index.tsx文件。这个入口文件很简单就是一个挂载import * as React from ‘react’import * as ReactDOM from ‘react-dom’ReactDOM.render(( <div> test </div>), document.getElementById(‘root’))ok,打开页面可以看到页面正常显示了test字样。我们需要创建Calendar组件了。创建一个components文件夹,内部创建一个Calendar.tsx文件。import * as React from ‘react’export default class Calendar extends React.Component { render() { return (<div> 日历 </div>) }}在index.tsx中把Calendar.tsx引入,并使用起来。于是index.tsx变成这个样子。import * as React from ‘react’import * as ReactDOM from ‘react-dom’import Calendar from ‘./components/Calendar’ReactDOM.render(( <div> <Calendar/> </div>), 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 (<div> <table cellPadding={0} cellSpacing={0} className=“table”> <thead> <tr> { WEEK_NAMES.map((week, key) => { return <td key={key}>{week}</td> }) } </tr> </thead> <tbody> { LINES.map((l, key) => { return <tr key={key}> { WEEK_NAMES.map((week, index) => { return <td key={index}>{index}</td> }) } </tr> }) } </tbody> </table> </div>) }}可以看到我们使用了一个星期数组作为表头,我们按照惯例是从周日开始的。你也可以从其他星期开始,不过会对下面的日期显示有影响,因为每个月的第一天是周几决定第一天显示在第几个格子里。那为什么行数要6行呢?因为我们是按照最大行数来确定表格的行数的,如果一个月有31天,而这个月的第一天刚好是周六。就肯定会显示6行了。为了显示好看,我直接写好了样式放置在index.html中了,这个不重要,不讲解。<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Document</title> <style type=“text/css”> * { margin: 0; padding: 0; } .table { border-collapse:collapse; border-spacing:0; } .table td{ border: 1px solid #ddd; padding: 10px; } .table caption .caption-header{ border-top: 1px solid #ddd; border-right: 1px solid #ddd; border-left: 1px solid #ddd; padding: 10px; display: flex; justify-content: space-between; } .table caption .caption-header .arrow { cursor: pointer; font-family: “宋体”; transition: all 0.3s; } .table caption .caption-header .arrow:hover { opacity:0.7; } </style></head><body> <div id=“root”></div> <script src="./dist/main.js"></script></body></html>下面就要开始显示日期了,首先要把当前月份的日期显示出来,我们先在组件的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 <span>&nbsp;</span> } 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 <span>&nbsp;</span> } 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 (<div> {this.state.month} <table cellPadding={0} cellSpacing={0} className=“table”> <caption> <div className=“caption-header”> <span className=“arrow” onClick={this.monthChange.bind(this, -1)}>&#60;</span> <span>{year} - {Calendar.formatNumber(month)}</span> <span className=“arrow” onClick={this.monthChange.bind(this, 1)}>&gt;</span> </div> </caption> <thead> <tr> { WEEK_NAMES.map((week, key) => { return <td key={key}>{week}</td> }) } </tr> </thead> <tbody> { LINES.map((l, key) => { return <tr key={key}> { WEEK_NAMES.map((week, index) => { return <td key={index} style={{color: this.checkToday(key, index, weekDay, monthDays) ? ‘red’ : ‘#000’}}> {Calendar.getDayText(key, index, weekDay, monthDays)} </td> }) } </tr> }) } </tbody> </table> </div>) }}可以看到最终的代码多了一些东西,因为我加了月份的切换。还记的上文我们把二月份天数写28天嘛?要不你们自己改改,判断一下闰年。 ...

September 7, 2018 · 4 min · jiezi