Reflex 如何用事件动作控制 DOM 默认行为、阻止冒泡和事件节流【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflex在 Reflex 应用中组件上的事件触发器如on_click、on_scroll、on_change会把事件发送到后端的 Event Handler。但有些场景需要在前端层面改变事件的处理方式阻止链接点击后的默认跳转、阻止点击事件冒泡到父元素、或者对高频事件做节流与防抖以避免网络延迟。Reflex 的事件动作Event Actions就是干这个的它们通过访问 EventHandlers 和 EventSpecs 上已有的属性和方法来指定可以修改浏览器对 DOM 事件的处理也可以让事件在后端处理之前被节流或防抖。前置条件Python 3.10按 安装文档 用uv创建项目并初始化mkdir your-app cd your-app uv init uv add reflex uv run reflex init其中your-app替换为你的项目名初始化模板选择 (0) A blank Reflex app。运行应用uv run reflex run应用运行在 http://localhost:3000代码修改会热更新。以下示例中事件触发器如on_click、on_mouse_over是组件的 props每个组件支持哪些触发器见该组件的文档见 Events Overview。阻止默认行为prevent_default.prevent_default动作会阻止浏览器对事件的默认行为。它可以追加到任何已有事件后面也可以作为独立的事件处理器直接写成rx.prevent_default。典型用法是阻止链接点击后的跳转。文档中给出的最小示例自 v0.3.2 起可用rx.link( This Link Does Nothing, hrefhttps://reflex.dev/, on_clickrx.prevent_default )如果同时需要在不跳转的前提下更新状态可以把手动处理器链上该动作class LinkPreventDefaultState(rx.State): status: bool False rx.event def toggle_status(self): self.status not self.status def prevent_default_example(): return rx.vstack( rx.heading(fThe value is {LinkPreventDefaultState.status}, as_h2), rx.link( Toggle Value, hrefhttps://reflex.dev/, on_clickLinkPreventDefaultState.toggle_status.prevent_default, ), )运行后点击 Toggle Value 链接页面停留在原页面默认导航被阻止同时标题中的状态值发生翻转两者同时成立说明该动作生效了。阻止事件冒泡stop_propagation.stop_propagation动作会阻止事件向父元素传播。常见场景是一个可点击的容器内部嵌套了按钮你希望点击按钮时不要同时触发容器的on_click。下面的文档示例用两个按钮做对照自 v0.3.2 起可用class StopPropagationState(rx.State): where_clicked: list[str] [] rx.event def handle_click(self, where: str): self.where_clicked.append(where) rx.event def handle_reset(self): self.where_clicked [] def stop_propagation_example(): return rx.vstack( rx.button( btn1 - Stop Propagation, on_clickStopPropagationState.handle_click(btn1).stop_propagation, ), rx.button( btn2 - Normal Propagation, on_clickStopPropagationState.handle_click(btn2), ), rx.foreach(StopPropagationState.where_clicked, rx.text), rx.button( Reset, on_clickStopPropagationState.handle_reset.stop_propagation, ), padding2em, borderf1px dashed {rx.color(accent, 5)}, on_clickStopPropagationState.handle_click(outer), )外层rx.vstack挂了on_clickStopPropagationState.handle_click(outer)点击记录会追加到where_clicked并用rx.foreach渲染出来。验证方式是点击两个按钮对比结果点击 btn1 - Stop Propagation记录中只出现btn1outer不会追加点击 btn2 - Normal Propagation记录中会同时出现btn2和outer因为事件冒泡到了外层 vstack点击 Reset 清空记录。事件节流throttle.throttle限制事件在给定时间窗口内被处理的次数适用于on_scroll、on_mouse_move这类触发非常频繁、在后端处理时会导致卡顿的事件。参数是单个毫秒数值自 v0.5.0 起可用。文档示例把on_scroll节流为每 500 毫秒最多处理一次class ThrottleState(rx.State): last_scroll: datetime.datetime | None rx.event def handle_scroll(self): self.last_scroll datetime.datetime.now(datetime.timezone.utc) def scroll_box(): return rx.scroll_area( rx.heading(Scroll Me, as_h2), *[rx.text(fItem {i}) for i in range(100)], height75px, width50%, borderf1px solid {rx.color(accent, 5)}, on_scrollThrottleState.handle_scroll.throttle(500), ) def throttle_example(): return ( scroll_box(), rx.text( Last Scroll Event: , rx.moment(ThrottleState.last_scroll, formatHH:mm:ss.SSS), ), )页面显示Last Scroll Event:加一个HH:mm:ss.SSS格式的最近处理时间连续滚动时可以看到时间戳按节流间隔更新而不是每次都变。使用限制处于节流窗口内触发的事件会被直接丢弃不存在最终补发。因此 throttle 不适用于最终载荷中包含必须处理数据的事件比如on_change。事件防抖debounce.debounce把事件处理推迟到指定超时结束后执行如果在超时期间又触发了新事件计时器会重置原来的事件被丢弃。参数同样是毫秒数自 v0.5.0 起可用。它适合处理一系列事件的最终结果例如拖动滑块。文档示例中滑块的on_change处理器只在滑块值 500 毫秒内没有变化时才触发后端class DebounceState(rx.State): settled_value: int 50 rx.event def update_value(self, value: list[int | float]): self.settled_value value[0] def debounced_slider(): return rx.slider( keyrx.State.router.session.session_id, default_value[DebounceState.settled_value], on_changeDebounceState.update_value.debounce(500), width100%, ) def debounce_example(): return rx.vstack( debounced_slider(), rx.text(fSettled Value: {DebounceState.settled_value}), )注意示例中rx.slider上设置了keyrx.State.router.session.session_id配合动态的default_value这保证页面刷新后组件会重新渲染并显示 state 中更新的值不设key的话刷新后滑块会一直显示最初的settled_value。使用限制防抖期间触发的新事件会让原事件被丢弃所以 debounce 不适用于每个载荷都包含唯一数据、必须逐次处理的事件比如on_key_down。事件动作可以链式组合事件动作可以互相串联来构建更复杂的行为。文档给出的组合示例是节流 500 毫秒的同时阻止默认行为on_clickMyState.handle_click.throttle(500).prevent_default其中MyState.handle_click换成你实际的事件处理器即可。实现层面这些动作都由 EventActionsMixin 提供stop_propagation、prevent_default、temporal是属性throttle(limit_ms)、debounce(delay_ms)是带参数方法。适用范围与限制版本要求prevent_default和stop_propagation自 v0.3.2 起可用throttle和debounce自 v0.5.0 起可用低版本升级后再使用这些写法。throttle 与 debounce 的语义差异节流是限制单位时间内的处理次数防抖是等待事件停止后再处理一次两者在窗口内都会丢弃事件选型前先确认你的事件载荷是否允许丢失中间值。每个动作的用途说明以 Event Actions 文档 为准事件触发器本身支持哪些参数见各组件文档Events Overview。【免费下载链接】reflex️ Web apps in pure Python 项目地址: https://gitcode.com/GitHub_Trending/re/reflex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考