Agent Skillsflet-dev/flet › imperative-to-declarative-flet

imperative-to-declarative-flet

GitHub

将命令式 Flet Python 应用重构为声明式组件模式,使用组件装饰器、状态钩子和可观察模型,消除手动页面更新。

.agents/skills/imperative-to-declarative-flet/SKILL.md flet-dev/flet

Trigger Scenarios

需要将现有 Flet 应用从命令式转换为声明式风格 优化 Flet 应用的状态管理和 UI 渲染逻辑

Install

npx skills add flet-dev/flet --skill imperative-to-declarative-flet -g -y
More Options

Non-standard path

npx skills add https://github.com/flet-dev/flet/tree/main/.agents/skills/imperative-to-declarative-flet -g -y

Use without installing

npx skills use flet-dev/flet@imperative-to-declarative-flet

指定 Agent (Claude Code)

npx skills add flet-dev/flet --skill imperative-to-declarative-flet -a claude-code -g -y

安装 repo 全部 skill

npx skills add flet-dev/flet --all -g -y

预览 repo 内 skill

npx skills add flet-dev/flet --list

SKILL.md

Frontmatter
{
    "name": "imperative-to-declarative-flet",
    "metadata": {
        "short-description": "Port Flet app to declarative"
    },
    "description": "Convert an imperative Flet Python app in which controls are mutated and then page.update is called to declarative style using flet.component, flet.observable and state hooks."
}

Imperative → Declarative (Flet Python)

Port an existing imperative Flet app to “components mode” with @ft.component, hooks, and (optionally) @ft.observable models.

Outcomes

  • Original folder unchanged; new sibling folder created.
  • Entry point uses page.render(App) (components mode).
  • UI is derived from state; minimal/zero manual page.update() for normal UI updates.

Choose a state strategy

  • Use @ft.observable for nested app data you mutate in place (boards/lists/cards, drag+drop reorder).
  • Use ft.use_state for local ephemeral UI state (hover flags, input text, dialog selection).
  • Avoid storing live Control/component objects in state; store ids/enums and create controls during render.

Workflow

1) Create a new declarative copy

  • Copy the existing app folder to a new one (e.g. trollitrolli-declarative-*).
  • Keep assets/ with the new folder.

2) Switch to components mode entrypoint

  • Create a root component @ft.component def App(): ....
  • Run with:
    • ft.run(lambda page: page.render(App), assets_dir=...)
  • Set page globals either:
    • in a main(page) function before page.render(App), or
    • in ft.on_mounted(...) (works, but ordering can be less obvious).

3) Centralize routing in App

  • Keep app.route: str as source of truth.
  • In one place, define:
    • route_change(e) to normalize/redirect/validate routes and set app.route
    • a render-time match app.route (or a derived active_screen) to pick content
  • Prefer: route_change mutates route state; App() render chooses UI based on that state.

4) Componentize UI

  • Move UI chunks into src/components/*.py.
  • Each component:
    • takes only the model(s) it needs
    • uses hooks for local UI state
    • mutates observable models for app data changes

5) Dialogs: reduce page.update() usage

If a dialog mutates existing controls and calls page.update(), convert it to:

  • @ft.component dialog content with ft.use_state for error, selected_color, etc.
  • event handlers call setters (no explicit updates)
  • show it via page.show_dialog(ft.AlertDialog(content=DialogContent(...)))

6) Assets/fonts checklist

  • Prefer an absolute assets_dir derived from __file__.
  • If running via flet run, be aware it can set FLET_ASSETS_DIR and override assets_dir=.
  • Font registration uses the dict key as the font family name:
    • page.fonts = {"Pacifico": "Pacifico-Regular.ttf"}
    • use font_family="Pacifico".

Common pitfalls (and fixes)

  • Event handler typing is invariant (Event[Sub]Event[Base]):
    • If on_click is declared on Button, annotate e as ft.Event[ft.Button] (or use def handler(): ...).
  • TemplateRoute params are dynamic:
    • raw = getattr(troute, "id", None) then isinstance(raw, str) before int(raw).
  • controls=[*[...], ...] can confuse type checkers with components:
    • build lists in two steps and annotate/cast, or return raw controls from non-component factories.

Version History

  • 8f74fe9 Current 2026-08-20 12:12

Same Skill Collection

.agents/skills/create-flet-control-integration-tests/SKILL.md
.agents/skills/create-flet-example-projects/SKILL.md
.agents/skills/docs-build-and-verify/SKILL.md
.agents/skills/docs-conventions/SKILL.md
.agents/skills/fix-members-short-description/SKILL.md
.agents/skills/flet-deprecation/SKILL.md
.agents/skills/implement-flet-extension/SKILL.md
.agents/skills/prepare-flet-release/SKILL.md
.agents/skills/test-flet-apps-dev/SKILL.md
.agents/skills/update-flet-control-doc-gifs/SKILL.md
.agents/skills/write-changelog-entry/SKILL.md
website/.agents/skills/flet-release-announcement/SKILL.md
.agents/skills/run-unit-tests/SKILL.md
.agents/skills/run-integration-tests/SKILL.md

Metadata

Files
0
Version
8f74fe9
Hash
44e20a5a
Indexed
2026-08-20 12:12

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-26 03:24
浙ICP备14020137号-1 $방문자$