html5 自定义 datepicker,如何使用 React 构建自定义日期选择器(3)
本文作者:IMWeb howenhuo
未經同意,禁止轉載
Datepicker 組件
構建 Datepicker 組件
要開始構建 Datepicker 組件,請將以下代碼片段添加到 src/components/Datepicker/index.js 文件。
import React from "react";
import PropTypes from "prop-types";
import Calendar from "../Calendar";
import * as Styled from "./styles";
import { isDate, getDateISO } from "../../helpers/calendar";
class Datepicker extends React.Component{
state = { date: null, calendarOpen: false }
toggleCalendar = () => this.setState({ calendarOpen: !this.state.calendarOpen })
handleChange = evt => evt.preventDefault()
handleDateChange = date => {
const { onDateChanged } = this.props;
const { date: currentDate } = this.state;
const newDate = date ? getDateISO(date) : null;
currentDate !== newDate &&
this.setState({ date: newDate, calendarOpen: false }, () => {
typeof onDateChanged === "function" && onDateChanged(this.state.date);
});
}
componentDidMount() {
const { value: date } = this.props;
const newDate = date && new Date(date);
isDate(newDate) && this.setState({ date: getDateISO(newDate) });
}
componentDidUpdate(prevProps) {
const { value: date } = this.props;
const { value: prevDate } = prevProps;
const dateISO = getDateISO(new Date(date));
const prevDateISO = getDateISO(new Date(prevDate));
dateISO !== prevDateISO && this.setState({ date: dateISO });
}
}
Datepicker.propTypes = {
label: PropTypes.string,
value: PropTypes.string,
onDateChanged: PropTypes.func
}
export default Datepicker;
在這里,組件 state 初始化為兩個屬性:
date:一個 ISO string,表示日期選擇器的當前日期。格式是 “YYYY-MM-DD”。
calendarOpen :一個 boolean 標記,表示日期選擇器的日歷是否可見。
當組件 mount 時,Date 對象從傳遞給組件 props 的 value 解析,并更新 state,如componentDidMount() 方法所示。
handleDateChange() 方法以 Date 對象作為參數,并更新 state 下的 date。如果 Datepicker 組件的 props 傳遞了 onDateChanged 回調函數,則將使用更新的 ISO 日期字符串調用該函數。
渲染 datepicker
此時,值得一提的是,Bootstrap Dropdown 組件將用于模擬自定義日期選擇器的下拉效果。這就是為什么 Reactstrap 包被添加為此項目的依賴項的原因。
正如您很快會注意到,在日期選擇器中渲染的樣式化組件是 Reactstrap 下拉組件的樣式擴展。
更新 Datepicker 組件以包含 render() 方法,如下面的代碼片段所示。
class Datepicker extends React.Component {
// ... other methods here
render() {
const { label } = this.props;
const { date, calendarOpen } = this.state;
return (
{label || 'Enter Date'}
type="text"
value={date ? date.split("-").join(" / ") : ""}
onChange={this.handleChange}
readOnly="readonly"
placeholder="YYYY / MM / DD"
/>
{ calendarOpen && (
)}
);
}
}
Styled.DatePickerFormGroup 組件是一個 Bootstrap 的 .form-group,它包裝日期選擇器標簽和輸入字段。需要注意的是,輸入字段的類型是 “text”,并且標記為 readonly,這樣就無法直接編輯它。還要注意,輸入元素上的 change 事件的默認行為已經被阻止。
Styled.DatePickerDropdown 組件及其后代,是 Reactstrap 包 Dropdown 組件的樣式擴展。您可以在 這里 了解更多關于 Reactstrap 下拉列表的信息。
最后,Calendar 組件在下拉菜單中渲染,傳遞 state 中的 date 和 onDateChanged 回調函數的handleDateChange() 方法。
Datepicker 組件最終渲染的 DOM 應該如下所示(帶有一些樣式):
設置日期選擇器的樣式
將以下代碼片段添加到 src/components/Datepicker/styles.js,以創建日期選擇器所需的樣式組件。
import styled from 'styled-components';
import { FormGroup, Label, Input, Dropdown, DropdownToggle, DropdownMenu } from 'reactstrap';
export const DatePickerContainer = styled.div`
position: relative;
`;
export const DatePickerFormGroup = styled(FormGroup)`
display: flex;
justify-content: space-between;
position: relative;
width: 100%;
border: 2px solid #06c;
border-radius: 5px;
overflow: hidden;
`;
export const DatePickerLabel = styled(Label)`
margin: 0;
padding: 0 2rem;
font-weight: 600;
font-size: 0.7rem;
letter-spacing: 2px;
text-transform: uppercase;
color: #06c;
border-right: 2px solid #06c;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 102, 204, 0.05);
`;
export const DatePickerInput = styled(Input)`
padding: 1rem 2rem;
font-weight: 500;
font-size: 1rem;
color: #333;
box-shadow: none;
border: none;
text-align: center;
letter-spacing: 1px;
background: transparent !important;
display: flex;
align-items: center;
::placeholder {
color: #999;
font-size: 0.9rem;
}
`;
export const DatePickerDropdown = styled(Dropdown)`
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
`;
export const DatePickerDropdownToggle = styled(DropdownToggle)`
position: relative;
width: 100%;
height: 100%;
background: transparent;
opacity: 0;
filter: alpha(opacity=0);
`;
export const DatePickerDropdownMenu = styled(DropdownMenu)`
position: absolute;
top: 0;
left: 0;
width: 100%;
border: none;
padding: 0;
margin: 0;
transform: none !important;
`;
應用程序組件
最后,更新 src/App.js 文件,看起來像下面的代碼片段。
import React, { Component } from "react";
import Datepicker from "./components/Datepicker";
class App extends Component {
render() {
return (
);
}
}
export default App;
如果您按照本文和代碼片段進行操作,則應該在 React 應用程序中渲染出一個可用的自定義日期選擇器。
結論
在本教程中(1、2、3),您已經能夠逐步了解如何構建一個定制的 React 日期選擇器組件,該組件可以作為原生 HTML5 日期選擇器輸入元素的替代。
雖然本教程中創建的自定義日期選擇器能按預期工作,但它并不能完全滿足日期選擇器元素的所有要求。可以進一步改進,例如:
通過 props 實現 max 和 min 日期
將輸入類型從 “text” 切換到 “date”
更好的可訪問性改進
你可以在 react-datepicker-demo 的 GitHub 上獲得這個自定義日期選擇器的更多改進版本的完整源代碼。 您還可以在 Code Sandbox 上查看演示。
總結
以上是生活随笔為你收集整理的html5 自定义 datepicker,如何使用 React 构建自定义日期选择器(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OHotfix.exe是什么进程 Win
- 下一篇: 软件测试ipad电池,ipad2020电