IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 2021SC@SDUSC amis代码分析(1) -> 正文阅读

[JavaScript知识库]2021SC@SDUSC amis代码分析(1)

2021SC@SDUSC

概述

本周,我主要阅读和分析了calendar部分的代码。代码目录如下:
calendar代码目录
主要实现的不同功能组件包括:

  • 日期选择器
  • 日期时间选择器
  • 日期范围选择器
  • 日期时间范围选择器
  • 月份选择器

amis提供了非常完备的通过json生成日期选择器的组件API,可通过参数进行自定义配置,实现强大的功能。

示例

{
  "type": "page",
  "body": {
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-date",
        "name": "date",
        "label": "日期"
      }
    ]
  }
}

效果

在这里插入图片描述

代码分析

Year|Month 选择的实现

如下图所示:
在这里插入图片描述
在这里插入图片描述
选择年份和月份的基本逻辑是一样的,代码结构也很类似。以下,我使用月份选择的代码进行分析:

MonthsView.js

该文件使用create-react-class创建了基本月份选择的react组件模板

'use strict';

var React = require('react'),
	createClass = require('create-react-class')
;

// 使用 React.createElement创建基本 react 页面标签
var DateTimePickerMonths = createClass({
	render: function() {
		return React.createElement('div', { className: 'rdtMonths' }, [
			React.createElement('table', { key: 'a' }, React.createElement('thead', {}, React.createElement('tr', {}, [
			    // 前一个月
				React.createElement('th', { key: 'prev', className: 'rdtPrev', onClick: this.props.subtractTime( 1, 'years' )}, React.createElement('span', {}, '?' )),
				// 当前月份
				React.createElement('th', { key: 'year', className: 'rdtSwitch', onClick: this.props.showView( 'years' ), colSpan: 2, 'data-value': this.props.viewDate.year() }, this.props.viewDate.year() ),
				// 后一个月
				React.createElement('th', { key: 'next', className: 'rdtNext', onClick: this.props.addTime( 1, 'years' )}, React.createElement('span', {}, '?' ))
			]))),
			React.createElement('table', { key: 'months' }, React.createElement('tbody', { key: 'b' }, this.renderMonths()))
		]);
	},

	renderMonths: function() {
		// viewDate 是来自父组件的 moment.Moment 对象
		var date = this.props.selectedDate, //选择的日期
			month = this.props.viewDate.month(),//当前月份
			year = this.props.viewDate.year(),//当前年份
			rows = [],
			i = 0,//所选择的月份
			months = [],
			renderer = this.props.renderMonth || this.renderMonth,
			isValid = this.props.isValidDate || this.alwaysValidDate,
			classes, props, currentMonth, isDisabled, noOfDaysInMonth, daysInMonth, validDay,
			// 日期无关紧要,因为我们只对月份感兴趣
			irrelevantDate = 1
			;

		while (i < 12) {
			classes = 'rdtMonth';
			// 克隆 viewDate 并根据 i 的值更改状态
			currentMonth =
				this.props.viewDate.clone().set({ year: year, month: i, date: irrelevantDate });
			// 获取该月的结束时间
			noOfDaysInMonth = currentMonth.endOf( 'month' ).format( 'D' );
			// 该月的日期数组
			daysInMonth = Array.from({ length: noOfDaysInMonth }, function( e, i ) {
				return i + 1;
			});
			// 有效日期
			validDay = daysInMonth.find(function( d ) {
				// 克隆,更新日期
				var day = currentMonth.clone().set( 'date', d );
				// 检查是否已经是实例化对象
				return isValid( day );
			});
			// 无效 当不存在有效日期时
			isDisabled = ( validDay === undefined );
			// 无效时设置样式
			if ( isDisabled )
				classes += ' rdtDisabled';
			// 如果是当前日期时设置样式
			if ( date && i === date.month() && year === date.year() )
				classes += ' rdtActive';
			// 整理数据 key | 'data-value' | className
			props = {
				key: i,
				'data-value': i,
				className: classes
			};
			// 有效时
			if ( !isDisabled )
				// 增加属性 onClick
				props.onClick = ( this.props.updateOn === 'months' ?
					// 如果更新模式是月份,就更新;反之将模式变更为月份
					this.updateSelectedMonth : this.props.setDate( 'month' ) );
			// 整理 i 月的数据
			months.push( renderer( props, i, year, date && date.clone() ) );
			// 每4个月一行
			if ( months.length === 4 ) {
				rows.push( React.createElement('tr', { key: month + '_' + rows.length }, months ) );
				months = [];
			}

			i++;
		}

		return rows;
	},
	// 调用父组件的选择新月份后的更新函数
	updateSelectedMonth: function( event ) {
		this.props.updateSelectedDate( event );
	},

	renderMonth: function( props, month ) {
		var localMoment = this.props.viewDate;
		// 获取月份字符串
		var monthStr = localMoment.localeData().monthsShort( localMoment.month( month ) );
		var strLength = 3;
		// Because some months are up to 5 characters long, we want to
		// use a fixed string length for consistency
		// 去掉前缀
		var monthStrFixedLength = monthStr.substring( 0, strLength );
		return React.createElement('td', props, capitalize( monthStrFixedLength ) );
	},

	alwaysValidDate: function() {
		return 1;
	},
});

// 首字母大写
function capitalize( str ) {
	return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
}

module.exports = DateTimePickerMonths;

MonthsView.jsx

该文件继承自MonthsView.js

// @ts-ignore
import MonthsView from 'react-datetime/src/MonthsView'; 
// moment 第三方库
import moment from 'moment';
import React from 'react';
// 本地工具文件
import {LocaleProps, localeable, TranslateFn} from '../../locale';

export interface OtherProps {
  // 输入样式
  inputFormat?: string;
}

export class CustomMonthsView extends MonthsView {
  props: {
  	// 传入 viewDate = moment.Moment
    viewDate: moment.Moment;
    // 减少时间函数
    subtractTime: (
      amount: number,
      type: string,
      toSelected?: moment.Moment
    ) => () => void;
	// 增加时间函数
    addTime: (
      amount: number,
      type: string,
      toSelected?: moment.Moment
    ) => () => void;
    // 选择面板展示函数
    showView: (view: string) => () => void;
  } & LocaleProps &
    OtherProps;
  renderMonths: () => JSX.Element;
  // 重写方法
  renderMonth = (props: any, month: number) => {
    var localMoment = this.props.viewDate;
    var monthStr = localMoment
      .localeData()
      .monthsShort(localMoment.month(month));
    var strLength = 3;
    // Because some months are up to 5 characters long, we want to
    // use a fixed string length for consistency
    var monthStrFixedLength = monthStr.substring(0, strLength);
    return (
      <td {...props}>
        <span>{monthStrFixedLength}</span>
      </td>
    );
  };
  render() {
  	// 语言及样式
    const __ = this.props.translate;
    const showYearHead = !/^mm$/i.test(this.props.inputFormat || '');
    const canClick = /yy/i.test(this.props.inputFormat || '');
	// 渲染的树结构
    return (
      <div className="rdtMonths">
        {showYearHead && (
          <table>
          // 年份增减
            <thead>
              <tr>
                <th
                  className="rdtPrev"
                  onClick={this.props.subtractTime(1, 'years')}
                >
                  &laquo;
                </th>
                {canClick ? (
                  <th
                    className="rdtSwitch"
                    onClick={this.props.showView('years')}
                  >
                    {this.props.viewDate.format(__('dateformat.year'))}
                  </th>
                ) : (
                  <th className="rdtSwitch">
                    {this.props.viewDate.format(__('dateformat.year'))}
                  </th>
                )}

                <th
                  className="rdtNext"
                  onClick={this.props.addTime(1, 'years')}
                >
                  &raquo;
                </th>
              </tr>
            </thead>
          </table>
        )}
		// 月份选择
        <table>
          <tbody>{this.renderMonths()}</tbody>
        </table>
      </div>
    );
  }
}

export default localeable(CustomMonthsView as any);

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:25:59  更:2021-10-11 17:27:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 18:16:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码