十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Reflex 组件实战:用 rx.segmented_control 构建互斥选项切换器(Radix Segmented Control 完全指南)

Reflex 组件实战:用 rx.segmented_control 构建互斥选项切换器(Radix Segmented Control 完全指南) Reflex 组件实战用 rx.segmented_control 构建互斥选项切换器Radix Segmented Control 完全指南【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflexSegmented Control分段控制器是 Reflex 内置的 Radix Themes 组件它把一组互斥选项如「收件箱 / 草稿 / 已发送」组合成一个高亮当前选中项的控件帮助用户在预定义值和视图之间快速切换。本指南以 docs/library/disclosure/segmented_control.md 为核心结合仓库中 segmented_control.py 的源码实现与集成测试带你掌握它的全部 props、状态绑定、动态渲染与源码级实现细节读完即可在纯 Python 的 Reflex 应用中落地使用。Segmented Control 是什么Segmented Control 用一组相邻的分段按钮呈现互斥选项——同一时刻只有一个选项处于激活状态视觉上由一块滑动的指示器indicator标出当前选中项。相比下拉菜单dropdown或散落的多个按钮它把相关选项在视觉上归组当前状态一目了然交互也更直接、可访问。在 Reflex 中该组件由两部分构成rx.segmented_control.root外层容器负责分组、当前值、样式与事件rx.segmented_control.item单个分段定义标签label和唯一标识value。两者在源码中分别对应SegmentedControlRoot与SegmentedControlItem两个类并通过SegmentedControl命名空间以root/item静态方法暴露定义见 segmented_control.py。该模块通过 mappings.py 中的懒加载映射按需导入不会拖慢应用启动。基本用法root 组合 item创建一个 Segmented Control 只需要在rx.segmented_control.root内放入若干rx.segmented_control.item。每个 item 需要一个人类可读的标签和唯一valueimport reflex as rx def segmented_demo() - rx.Component: return rx.segmented_control.root( rx.segmented_control.item(Home, valuehome), rx.segmented_control.item(About, valueabout), rx.segmented_control.item(Test, valuetest), )root负责把 items 组合成整体item的value是组件内部使用的唯一标识当用户选中某个分段时该 value 会通过事件回调传递出来详见下一节。用 State 绑定选中值on_change 与 value要让控件真正「活」起来需要把它接入 Reflex 的 State。文档中的基础示例定义了一个状态类用control变量保存当前选中值并用事件处理器set_control接收用户的选择import reflex as rx class SegmentedState(rx.State): The app state. control: str test rx.event def set_control(self, value: str | list[str]): self.control value注意set_control的参数类型是str | list[str]Segmented Control 在typemultiple模式下会一次性回传多个选中值因此事件处理器的签名需要同时兼容单选与多选。这与源码中on_value_change事件处理函数的签名value: Var[str | list[str]]完全一致见 segmented_control.py。接着把控件与状态双向绑定def basic_example() - rx.Component: return rx.vstack( rx.segmented_control.root( rx.segmented_control.item(Home, valuehome), rx.segmented_control.item(About, valueabout), rx.segmented_control.item(Test, valuetest), on_changeSegmentedState.set_control, valueSegmentedState.control, ), rx.card( rx.text(SegmentedState.control, alignleft), rx.text(SegmentedState.control, aligncenter), rx.text(SegmentedState.control, alignright), width100%, ), )在这个示例中on_change指定回调函数用户切换分段时调用SegmentedState.set_control把新选中的 value 写入control状态变量value指定当前选中的分段与SegmentedState.control绑定实现受控组件——状态变化会驱动控件重新渲染卡片中三段文字也会同步显示当前值。也就是说on_change负责「用户 → 状态」的数据流value负责「状态 → 控件」的回显二者配合才能保证 UI 与状态始终一致。完整 props 参考rx.segmented_control.root支持的配置项在 SegmentedControlRoot 中以 field 形式声明汇总如下属性类型说明size1 \| 2 \| 3支持响应式值控件尺寸1最小、3最大variantclassic \| surface视觉风格classic为经典边框样式surface为表面填充样式typesingle \| multiple选择模式single单选默认multiple可多选color_scheme强调色字面量如tomato、blue、indigo等覆盖主题的强调色用于选中态高亮radiusnone \| small \| medium \| large \| full圆角大小default_valuestr \| Sequence[str]非受控模式下的默认选中值valuestr \| Sequence[str]受控模式下的当前选中值on_change事件处理器处理onChange事件回传str \| list[str]其中color_scheme可用的强调色集合tomato、red、ruby、crimson、pink、plum、violet、iris、indigo等定义在 base.py 的 LiteralAccentColorradius的字面量类型与 Radix Themes 的LiteralRadius保持一致见同一文件的 base.py。rx.segmented_control.item则只有一个核心属性value字符串作为该分段的唯一标识并且仅允许作为SegmentedControlRoot的子组件出现——源码通过_valid_parents [SegmentedControlRoot]约束了父子关系见 segmented_control.py。单选与多选默认typesingle时一次只能选中一个分段当需要允许同时选择多个值时设置typemultiple此时on_change会以列表形式回传所有选中项的 value事件处理器可这样处理import reflex as rx class MultiState(rx.State): selected: list[str] [] rx.event def on_select(self, value: str | list[str]): self.selected value if isinstance(value, list) else [value] def multi_example() - rx.Component: return rx.segmented_control.root( rx.segmented_control.item(Python, valuepy), rx.segmented_control.item(JavaScript, valuejs), rx.segmented_control.item(Rust, valuers), typemultiple, on_changeMultiState.on_select, valueMultiState.selected, )需要说明的是源码注释指出typemultiple时不会注入滑动指示器的自定义样式单个滑动指示器无法表达多个选中态Radix 默认的 nth-child 规则依然生效详见 segmented_control.py。动态渲染结合 rx.foreach当选项是动态数据时可以用rx.foreach在root内批量生成item。仓库集成测试 test_appearance.py 中有一个用 11 个选项渲染控件的完整示例import reflex as rx class SegmentedState(rx.State): options: list[str] [str(i) for i in range(1, 12)] control: str 1 rx.event def set_control(self, value: str | list[str]): self.control value if isinstance(value, str) else value[0] def many_items_example() - rx.Component: return rx.segmented_control.root( rx.foreach( SegmentedState.options, lambda label: rx.segmented_control.item(label, valuelabel), ), on_changeSegmentedState.set_control, valueSegmentedState.control, )源码中的_collect_item_values专门处理了这种场景它会识别「单个rx.foreach生成 items」或「扁平列表的SegmentedControlItem」两种子组件形态并提取出有序的 value 列表用于后续的指示器定位计算其余形态则回退到 Radix 默认行为见 segmented_control.py。源码级深入超过 10 个选项的指示器修复SegmentedControlRoot.create与add_style是理解该组件底层原理的关键。Radix Themes 3.3.0 在radix-ui/themes#730中硬编码了最多 10 个 item 的指示器宽度 / 位移 CSS 规则当选项超过 10 个时指示器会塌缩为零宽度。Reflex 通过注入 CSS 自定义属性绕过此限制在create中非multiple模式下若能从子组件中收集到 value 列表且提供了value或default_value就把--rx-sc-countitem 总数与--rx-sc-idx选中项索引写入根节点的 style见 segmented_control.pyadd_style检测到这些自定义属性后覆盖指示器样式用calc()计算宽度与位移width: calc(100% / var(--rx-sc-count))、transform: translateX(calc(var(--rx-sc-idx) * 100%))使指示器对任意数量的 item 都正确对齐见 segmented_control.py。集成测试test_segmented_control_indicator_with_11_items专门验证了这一点它渲染 11 个 item点击第 11 个后断言指示器可见、宽度大于 0且与第 11 项的 x 坐标误差小于 2px见 test_appearance.py。也就是说日常使用 ≤10 个选项时无需关心此细节Radix 默认规则即可胜任选项更多时Reflex 的自动修复保证了指示器依然正确工作。实战案例颜色模式切换器仓库的集成测试还提供了一个非常实用的真实用例——用 Segmented Control 做主题颜色模式切换system/light/darkitem 内直接放置图标import reflex as rx from reflex_base.style import color_mode, resolved_color_mode, set_color_mode def color_toggle_example() - rx.Component: return rx.box( rx.segmented_control.root( rx.segmented_control.item( rx.icon(tagmonitor, size20), valuesystem, ), rx.segmented_control.item( rx.icon(tagsun, size20), valuelight, ), rx.segmented_control.item( rx.icon(tagmoon, size20), valuedark, ), on_changeset_color_mode, variantclassic, radiuslarge, valuecolor_mode, ), rx.text(color_mode, idcurrent_color_mode), rx.text(resolved_color_mode, idresolved_color_mode), )该示例展示了几个进阶要点源码见 test_appearance.pyitem 内容不限于纯文本可以放入rx.icon等任意组件作为分段标签样式组合variantclassic配合radiuslarge塑造更柔和的视觉绑定系统级状态on_changeset_color_mode直接使用 Reflex 内置的颜色模式切换函数valuecolor_mode回显当前模式构建出开箱即用的主题切换控件。小结rx.segmented_control是 Reflex 中实现互斥选项切换的首选组件root负责分组与状态同步item定义具体选项on_change与value完成与 State 的双向绑定size、variant、type、color_scheme、radius提供了丰富的定制空间。结合rx.foreach可以动态渲染任意数量的选项而底层源码对超过 10 个选项的指示器修复则保证了它在边界场景下依然稳定可用。无论是页面内的视图切换、筛选条件选择还是主题模式切换都可以用这一个组件优雅实现。【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表