ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

amis InputQuarterRange 季度范围组件详解:配置属性、取值格式与源码实现

amis InputQuarterRange 季度范围组件详解:配置属性、取值格式与源码实现 amis InputQuarterRange 季度范围组件详解配置属性、取值格式与源码实现【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis在 amis 低代码框架中input-quarter-range季度范围控件是表单体系里面向财报、销售看板等按季度筛选场景的专用选择器一次点击即可选定“开始季度—结束季度”区间并以逗号分隔的字符串写入表单数据。本文基于仓库中的组件文档与实现源码完整覆盖它的基本用法、内嵌模式、extraName双字段存储、全部配置属性、事件与动作机制并深入DateRangePicker与parseDuration等底层实现帮助你既会用、又懂其原理。组件定位季度范围选择器从源码结构看input-quarter-range是日期范围控件族的一员。它在 InputQuarterRange.tsx 中定义直接继承日期范围基类InputDateRange并复用 amis-ui 的DateRangePicker只是把弹层视图固定为viewModequarters季度视图// packages/amis/src/renderers/Form/InputQuarterRange.tsx export default class QuarterRangeControl extends InputDateRange { supportStatic() render() { // ... return ( div className{cx(${ns}DateRangeControl, className)} DateRangePicker viewModequarters // ... / /div ); } } FormItem({ type: input-quarter-range }) export class QuarterRangeControlRenderer extends QuarterRangeControl { static defaultProps { format: X, inputFormat: YYYY-[Q]Q, joinValues: true, delimiter: ,, /** shortcuts的兼容配置 */ ranges: thisquarter,prevquarter, shortcuts: thisquarter,prevquarter, animation: true }; }这段defaultProps揭示了几个文档属性表里没有直接写明的默认值存储格式默认XUnix 时间戳秒、显示格式默认YYYY-[Q]Q即2024-Q1这种形式、起止值默认用逗号joinValues delimiter拼成一个字符串、并且默认开启季度相关的快捷键thisquarter,prevquarter。弹层中每个季度单元格Q1Q4的渲染逻辑在 DateRangePicker.tsx 的renderQuarter中实现它用moment().year(year).quarter(quarter)定位每个季度并根据是否落在[startDate, endDate]区间内打上选中样式。基本用法在表单中声明一个input-quarter-range表单项即可使用最简配置如下文档示例可直接在 表单组件 体系中运行{ type: form, api: /api/mock2/form/saveForm, body: [ { type: input-quarter-range, name: quarter-range, label: 季度范围 } ] }选择完成后表单数据中quarter-range的值为起止两个时间戳按默认valueFormat: X存储以逗号分隔的字符串。仓库中的单元测试 inputQuarterRange.test.tsx 验证了这条链路点击输入框、在弹层中依次点选 Q1 和 Q4、确认之后两个输入框的显示值分别是2024-Q1当年与2024-Q4fireEvent.click(inputs[0]!); fireEvent.click( await within(document.querySelector(.cxd-DateRangePicker-start)!) .findByText(Q1) ); fireEvent.click( await within(document.querySelector(.cxd-DateRangePicker-start)!) .findByText(Q4) ); fireEvent.click(getByText(确认)); const thisYear moment().format(YYYY); expect((inputs[0] as HTMLInputElement).value).toEqual(${thisYear}-Q1); expect((inputs[1] as HTMLInputElement).value).toEqual(${thisYear}-Q4);这个测试同时说明显示格式2024-Q1与存储格式时间戳是两套独立的格式体系分别由displayFormat/valueFormat控制。内嵌模式embed配置embed: true后季度面板不再以弹层形式出现而是直接内联渲染在表单项位置适合作为页面固定筛选区使用{ type: form, api: /api/mock2/form/saveForm, debug: true, body: [ { type: input-quarter-range, name: quarter-range, label: 季度范围, embed: true } ] }测试用例 inputQuarterRange.test.tsx 对embed模式还叠加了自定义格式valueFormat: YYYY-MM、displayFormat: YYYY/MM并回显value: 2021-10,2021-12断言内联面板中起止两侧的激活季度rdtActive均落在 Q4。需要注意内嵌模式与焦点事件的关系文档事件表中明确focus/blur仅在非内嵌模式下触发。存成两个字段extraName默认情况下季度范围只会写入name指定的一个字段起止值用delimiter默认逗号拼接若配置extraName结束值会单独写入另一个字段。文档示例{ type: form, debug: true, api: /api/mock2/form/saveForm, body: [ { type: input-quarter-range, name: begin, extraName: end, label: 季度范围 } ] }这一行为不是季度组件独有的而是表单控件包装层的通用机制。在 wrapControl.tsx 中可以看到当model.extraName存在时onChange 会把区间值的第二部分单独写入extraName对应的字段即onChange(values[1], model.extraName, false, true)。因此表单提交后数据里会得到begin与end两个独立字段而不是一个逗号拼接的字符串便于后端直接按字段接收起止时间。属性表除了支持 普通表单项属性表 中的配置以外input-quarter-range还支持下面一些配置完整继承自文档属性表属性名类型默认值说明版本valueFormatstringX日期选择器值格式3.4.0displayFormatstringYYYY-DD日期选择器显示格式3.4.0placeholderstring请选择季度范围占位文本minDatestring限制最小日期用法同 限制范围maxDatestring限制最大日期用法同 限制范围minDurationstring限制最小跨度如 2quartermaxDurationstring限制最大跨度如4quarterutcbooleanfalse保存 UTC 值clearablebooleantrue是否可清除embedbooleanfalse是否内联模式animationbooleantrue是否启用游标动画2.2.0extraNamestring是否存成两个字段3.3.0popOverContainerSelectorstring弹层挂载位置选择器会通过querySelector获取6.4.0此外由于它继承自日期范围基类AMISDateRangeSchemaBase定义于 InputDateRange.tsx还可使用基类声明的这些属性delimiter分隔符默认逗号、format/valueFormat存储格式format为旧版写法、inputFormat/displayFormat显示格式旧版写作inputFormat、joinValues是否拼接值默认true、startPlaceholder/endPlaceholder起止占位符、borderModefull/half/none、transform日期数据处理函数用于自定义处理选择后的值以及ranges3.1.0 起废弃建议改用shortcuts。几个属性在源码中的解析路径值得展开minDate/maxDate渲染前会先经过filterDate(minDate, data, valueFormat || format)见 InputQuarterRange.tsx即支持在限制值里写表达式引用表单数据如${min}并按存储格式解析为 moment 对象。minDuration/maxDuration由 date.ts 中的parseDuration解析正则支持的单位包括second、minute、hour、day、week、month、quarter、year、weekday、millisecond可加复数s、可带/-前缀、支持小数最终生成moment.Duration传给弹层做跨度校验所以2quarter这种写法就是被这条正则直接命中的。popOverContainerSelector透传给DateRangePicker后通过querySelector获取挂载节点移动端mobileUI下弹层/弹窗统一挂载到env.getModalContainer桌面端默认也是env.getModalContainer该属性用于解决弹层被父容器overflow裁剪等问题。默认显示格式属性表中标注displayFormat默认值为YYYY-DD而从源码结构看渲染时的取值链是displayFormat || inputFormat且季度控件的defaultProps.inputFormat为YYYY-[Q]Q因此未显式配置displayFormat时实际呈现的是2024-Q1这类“年-季度”文本与上文测试断言一致。快捷键shortcuts季度控件的defaultProps中默认配置了shortcuts: thisquarter,prevquarter对应弹层左侧的快捷选项。这两个快捷项在 DateRangePicker.tsx 的availableShortcuts中定义thisquarter本季度startDate now.startOf(quarter)endDate now.endOf(quarter)prevquarter上季度startDate now.startOf(quarter).add(-1, quarter)endDate now.startOf(quarter).add(-1, day).endOf(day)。此外源码中还实现了可扩展的“高级范围”advancedRanges支持按正则解析的动态快捷键其中与季度直接相关的有两组NquartersagoN 个季度前到今天之前一天与Nquarterslater本季度起 N 个季度后。也就是说除了默认两项你还可以配置类似3quartersago的字符串快捷项获得“最近 3 个季度”这类常用筛选。配置形式为逗号分隔字符串或ShortCuts数组见 InputDateRange.tsx 的shortcuts声明。事件表当前组件会对外派发以下事件可以通过onEvent来监听这些事件并通过actions来配置执行的动作在actions中可以通过${事件参数名}或${event.data.[事件参数名]}来获取事件产生的数据详细请查看事件动作。[name]表示当前组件绑定的名称即name属性如果没有配置name属性则通过value取值。事件名称事件参数说明change[name]: string组件的值时间值变化时触发focus[name]: string组件的值输入框获取焦点(非内嵌模式)时触发blur[name]: string组件的值输入框失去焦点(非内嵌模式)时触发从实现上看change事件在基类 InputDateRange.tsx 的handleChange中派发它先调用dispatchEvent(change, resolveEventData(this.props, {value: nextValue}))随后无条件执行props.onChange(nextValue)写入表单focus/blur则分别在DateRangePicker的onFocus/onBlur回调中通过dispatchEvent派发事件参数里的值由resolveEventData结合name/value生成。动作表当前组件对外暴露以下特性动作其他组件可以通过指定actionType: 动作名称、componentId: 该组件id来触发这些动作动作配置可以通过args: {动作配置项名称: xxx}来配置具体的参数详细请查看事件动作。动作名称动作配置说明clear-清空reset-将值重置为初始值。6.3.0 及以下版本为resetValuesetValuevalue: string更新的时间区间值用,隔开更新数据依赖格式format例如 1640966400,1664553600这三个动作的落点在基类中clear/reset由 doAction 处理。clear直接调用弹层实例的this.dateRef?.clear()reset先从formStore.pristine表单初始数据或store.pristine中按name取出初始值取不到则回退到resetValue属性再调用this.dateRef?.reset(pristineVal)。这正是文档中“reset 将值重置为初始值”的含义——重置目标是表单 pristine 快照里该字段对应的值。setValue由 setData 处理。传入的字符串值先按delimiter拆成起止两段各自经filterDate解析后交给DateRangePicker.formatValue统一格式化最后调用onChange(value)写回表单。formatValue同样接收joinValues/delimiter/utc参数所以setValue传入1640966400,1664553600时间戳时会按当前format/valueFormat归一化后存储。移动端与静态渲染两点补充行为同样来自源码移动端适配render中透传了mobileUI标志移动端下DateRangePicker会把季度视图切换为日历弹层形态DateRangePicker.tsx 中对[days, months, quarters]视图启用移动端日历且弹层容器切换为env.getModalContainer。静态展示组件类上标注了supportStatic()StaticHoc.tsx当表单以静态模式渲染如详情展示、只读态时季度范围会按纯文本形式展示起止季度而不是可交互的弹层。小结input-quarter-range是 amis 表单中“按季度筛选”的标准答案默认以X时间戳格式存一个逗号分隔的字段可用valueFormat/displayFormat调整存储与展示格式用extraName拆成两个字段用minDate/maxDate支持表达式与minDuration/maxDuration如2quarter由parseDuration校验约束可选范围配合thisquarter/prevquarter/Nquartersago等快捷键覆盖常见报表场景并通过change/focus/blur事件与clear/reset/setValue动作接入 amis 的事件动作体系。其实现位于 InputQuarterRange.tsx底层依赖 DateRangePicker.tsx行为验证见 inputQuarterRange.test.tsx可视化配置则对应编辑器插件 InputQuarterRange.tsx。【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表