博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
时间选择控件YearPicker(基于React,antd)
阅读量:6116 次
发布时间:2019-06-21

本文共 7089 字,大约阅读时间需要 23 分钟。

不知道为什么蚂蚁金服团队没有在ant design的DatePicker中单独给出选择年份的组件,这给我们这种懒人造成了很大的痛苦,自己手造轮子是很麻烦的。毕竟只是一个伸手党,emmmmm.....

然后就打算自己手撸了,首先去偷看了蚂蚁自己组件的样式,打算照着搬下来。后来发现下面的item是用的table布局,这种布局是我最厌恶的,还是换种方式吧,ul>li,嗯,我最喜欢的

然后开始。

 

 

代码如下:

/**  * 使用方法 * 引入: * import YearPicker from "@/common/widget/YearPicker";//路径按照自己的来 * // 获取年份值  filterByYear = value => {    console.log(value);  }; * 
*/import React, { Component } from "react";import { Icon } from "antd";import "../css/calendar.less";//这个文件自己选择一个温暖的地方放class YearPicker extends Component { constructor(props) { super(props); this.state = { isShow: false, selectedyear: "", years: [] }; } componentWillMount() { let { defaultValue } = this.props; this.setState({ selectedyear: defaultValue }); } componentDidMount() { let _this = this; document.addEventListener( "click", function(e) { const { isShow } = _this.state; let clsName = e.target.className; if ( clsName.indexOf("calendar") === -1 && e.target.tagName !== "BUTTON" && isShow ) { _this.hide(); } }, false ); } //初始化数据处理 initData = (operand, defaultValue) => { operand = operand ? operand : 12; let year = defaultValue - 1970; let curr = year % operand; let start = defaultValue - curr; let end = defaultValue + operand - 1 - curr; this.getYearsArr(start, end); }; // 获取年份范围数组 getYearsArr = (start, end) => { let arr = []; for (let i = start; i <= end; i++) { arr.push(Number(i)); } this.setState({ years: arr }); }; // 显示日历年组件 show = () => { const { selectedyear } = this.state; let { operand } = this.props; operand = operand ? operand : 12; this.initData(operand, selectedyear); this.setState({ isShow: true }); }; // 隐藏日期年组件 hide = () => { this.setState({ isShow: false }); }; // 向前的年份 prev = () => { const { years } = this.state; if (years[0] <= 1970) { return; } this.getNewYearRangestartAndEnd("prev"); }; // 向后的年份 next = () => { this.getNewYearRangestartAndEnd("next"); }; // 获取新的年份 getNewYearRangestartAndEnd = type => { const { selectedyear, years } = this.state; let operand = Number(this.props.operand); operand = operand ? operand : 12; let start = Number(years[0]); let end = Number(years[years.length - 1]); let newstart; let newend; if (type == "prev") { newstart = parseInt(start - operand); newend = parseInt(end - operand); } if (type == "next") { newstart = parseInt(start + operand); newend = parseInt(end + operand); } this.getYearsArr(newstart, newend); }; // 选中某一年 selects = e => { let val = Number(e.target.value); this.hide(); this.setState({ selectedyear: val }); if (this.props.callback) { this.props.callback(val); } }; render() { const { isShow, years, selectedyear } = this.state; return (
{isShow ? (
) : ( "" )}
); }}const List = props => { const { data, value, prev, next, cback } = props; return (
{value}
    {data.map((item, index) => (
  • ))}
);};export default YearPicker;

less代码:

@focuscolor: #108ee9;@bordercolor: #d9d9d9; /*这部分根据你自己的容器样式,我这个地方是因为公用组件的原因需要设置*/#wrapper .toolbar {
overflow: inherit !important;}#wrapper .toolbar > div:after {
content: ""; display: block; visibility: hidden; width: 0; clear: both;}/*---以下为必备样式----*/.calendar-wrap {
position: relative; .calendar-input { width: 151px; position: relative; cursor: pointer; .calendar-icon { position: absolute; right: 10px; top: 10px; color: #919191; } input {
width: 151px; height: 31px; border: 1px solid @bordercolor; border-radius: 4px; font-size: 12px; outline: none; display: block; padding: 6px 7px; transition: all 0.3s; &:hover, &:active { border-color: @focuscolor; } } } .calendar-container {
width: 232px; outline: none; border-radius: 4px; box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2); border: 1px solid @bordercolor; position: absolute; top: 0; left: 0; z-index: 999; background-color: #fff; line-height: 1.5; } .calendar-head-year {
height: 34px; line-height: 34px; text-align: center; width: 100%; position: relative; border-bottom: 1px solid #e9e9e9; .calendar-year-range { padding: 0 2px; font-weight: bold; display: inline-block; color: rgba(0, 0, 0, 0.65); line-height: 34px; } .calendar-btn {
position: absolute; top: 0; color: rgba(0, 0, 0, 0.43); padding: 0 5px; font-size: 12px; display: inline-block; line-height: 34px; cursor: pointer; &:hover { color: @focuscolor; } } .prev-btn {
left: 7px; } .next-btn {
right: 7px; } } .calendar-body-year {
width: 100%; height: 218px; .calendar-year-ul { list-style: none; .calendar-year-li { float: left; text-align: center; width: 76px; cursor: pointer; > button { cursor: pointer; outline: none; border: 0; display: inline-block; margin: 0 auto; color: rgba(0, 0, 0, 0.65); background: transparent; text-align: center; height: 24px; line-height: 24px; padding: 0 6px; border-radius: 4px; transition: background 0.3s ease; margin: 14px 0; &:hover { color: @focuscolor; } } } .calendar-year-selected {
> button { background: #108ee9; color: #fff; &:hover { color: #fff; } } } } }}

以上代码在IE10,11、FireFox, Chrome, Safari下亲测兼容良好

接下来说说,这个过程中遇到的问题:

1、点击组件外部任意地方需要关闭控件

以为显示的属性设置在组件内部的state中,因此当时有点懵逼,一开始想用redux store来控制,然后觉得这个强行依赖太恶心了,放弃

然后,想到在document上绑定click事件,虽然有点违背react不直接操作dom的原则。但是这是我这种智商能想到的比较好的方式了

(偷偷看了蚂蚁的方式,将整个选择的组件与input框隔离成独立的部分,采用 类似全屏遮罩层的方式,检测input在窗口中的位置来设置展示组件的位置,这样确实对于控制点击外部任意处关闭控件。但是这样属于一个控件的东西被拆分不是我这种一根筋的人能接受的)

so, 我还是倔强的使用了自己的方式

componentDidMount() {    let _this = this;    document.addEventListener(      "click",      function(e) {        const { isShow } = _this.state;        let clsName = e.target.className;        if (          clsName.indexOf("calendar") === -1 &&          e.target.tagName !== "BUTTON" &&          isShow        ) {          _this.hide();        }      },      false    );  }

2. 当外部容器设置了overflow:hidden 的情况时,控件会被遮挡

这个问题的话,额, 我就是去掉overflow:hidden, 然后给容器清除浮动或者设置固定高度

(一般需要设置overflow:hidden也是因为使用了浮动)

好了,我废话就这么多了,哈哈哈

转载于:https://www.cnblogs.com/zyl-Tara/p/9133524.html

你可能感兴趣的文章
Chrome浏览器播放HTML5音频没声音的解决方案
查看>>
easyui datagrid 行编辑功能
查看>>
类,对象与实例变量
查看>>
HDU 2818 (矢量并查集)
查看>>
【转】php字符串加密解密
查看>>
22. linux 常用命令
查看>>
ASP.Net 使用GridView模板删除一行的用法
查看>>
(十六)字段表集合
查看>>
JPGraph
查看>>
实验二 Java面向对象程序设计
查看>>
------__________________________9余数定理-__________ 1163______________
查看>>
webapp返回上一页 处理
查看>>
新安装的WAMP中phpmyadmin的密码问题
查看>>
20172303 2017-2018-2 《程序设计与数据结构》第5周学习总结
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
Content Provider的权限
查看>>
416. Partition Equal Subset Sum
查看>>
centos7.0 64位系统安装 nginx
查看>>