React中如何让input type="date"仅显示月日?或有无月日选择组件?
解决React中仅显示/选择日和月的问题
首先得明确一点:原生的<input type="date">没办法直接通过属性配置只显示日和月——这个控件的显示格式由浏览器和系统区域设置控制,而且它的取值逻辑必须包含年份(哪怕你不需要,底层也会带默认年份)。不过我们有几种靠谱的方案来实现你的需求:
方案1:用隐藏的原生date控件+自定义显示层
这个方法既能保留原生日期选择器的交互体验,又能自定义显示内容:
import { useState } from 'react'; const MonthDayPicker = () => { const [displayValue, setDisplayValue] = useState(''); const [hiddenDate, setHiddenDate] = useState(''); const handleDateChange = (e) => { const date = new Date(e.target.value); // 格式化显示为dd-mm const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); setDisplayValue(`${day}-${month}`); setHiddenDate(e.target.value); // 保存完整日期(带年份),方便后续业务处理 }; return ( <div style={{ position: 'relative' }}> {/* 隐藏原生date控件,点击显示层触发它 */} <input type="date" value={hiddenDate} onChange={handleDateChange} style={{ position: 'absolute', opacity: 0, width: '100%', height: '100%', cursor: 'pointer' }} /> {/* 自定义显示层 */} <input type="text" value={displayValue} readOnly style={{ padding: '8px', border: '1px solid #ccc', width: '120px' }} placeholder="dd-mm" /> </div> ); }; export default MonthDayPicker;
原理是把原生date控件设为透明覆盖在显示层上,用户点击显示层时实际触发原生选择器,选择后我们提取日和月来展示,同时保留完整的日期值供业务逻辑使用。
方案2:自定义月日选择组件(纯原生React)
如果不需要原生日期选择器的弹窗,也可以直接用两个<select>来实现,完全可控:
import { useState } from 'react'; const MonthDayPicker = () => { const [day, setDay] = useState(''); const [month, setMonth] = useState(''); // 生成月份选项 const months = Array.from({ length: 12 }, (_, i) => ({ value: String(i + 1).padStart(2, '0'), label: new Date(2024, i).toLocaleString('default', { month: 'short' }) })); // 根据月份生成日期选项(简单处理,实际可以考虑闰年/不同月份天数) const getDays = () => { if (!month) return []; const daysInMonth = new Date(2024, parseInt(month), 0).getDate(); return Array.from({ length: daysInMonth }, (_, i) => String(i + 1).padStart(2, '0')); }; return ( <div style={{ display: 'flex', gap: '8px' }}> <select value={month} onChange={(e) => setMonth(e.target.value)}> <option value="">选择月份</option> {months.map(m => ( <option key={m.value} value={m.value}>{m.label}</option> ))} </select> <select value={day} onChange={(e) => setDay(e.target.value)} disabled={!month}> <option value="">选择日期</option> {getDays().map(d => ( <option key={d} value={d}>{d}</option> ))} </select> <span>当前选择:{day && month ? `${day}-${month}` : '未选择'}</span> </div> ); }; export default MonthDayPicker;
这个方案的优点是完全自定义样式和逻辑,缺点是没有原生日期选择器的日历弹窗体验。
方案3:使用第三方日期选择组件
很多React日期组件支持仅选择月日的配置,比如react-datepicker:
首先安装依赖(如果还没装):
npm install react-datepicker # 或者 yarn add react-datepicker
然后使用组件并配置仅选择月日:
import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; import { useState } from 'react'; const MonthDayPicker = () => { const [selectedDate, setSelectedDate] = useState(null); return ( <DatePicker selected={selectedDate} onChange={(date) => setSelectedDate(date)} dateFormat="dd-MM" showMonthYearPicker={false} showFullMonthYearPicker={false} shouldCloseOnSelect={true} placeholderText="选择日-月" /> ); }; export default MonthDayPicker;
这个方案兼顾了日历弹窗体验和自定义显示格式,是比较推荐的方案,前提是你愿意引入第三方库。
关于原生input的CSS hack(不推荐)
网上有些教程会教用CSS隐藏年份字段,比如针对Chrome:
input[type="date"]::-webkit-datetime-edit-year-field { display: none; }
但这个方法兼容性极差——不同浏览器(Firefox、Safari)的内部DOM结构不一样,而且浏览器更新可能会打破这个hack,所以不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Pol Pol
相关产品推荐
相关产品推荐

