Jelajahi Sumber

began with SPA demo; still heavy work in progress

Rodja Trappe 2 tahun lalu
induk
melakukan
441f851265

+ 34 - 0
examples/single_page_app/main.py

@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+from router import Router
+
+from nicegui import ui
+
+router = Router()
+
+
+@router.add('/')
+async def show_one():
+    ui.label('Content One').classes('text-2xl')
+
+
+@router.add('/two')
+async def show_two():
+    ui.label('Content Two').classes('text-2xl')
+
+
+@router.add('/three')
+async def show_three():
+    ui.label('Content Three').classes('text-2xl')
+
+
+with ui.row():
+    ui.button('One', on_click=lambda: router.open(show_one)).classes('w-32')
+    ui.button('Two', on_click=lambda: router.open(show_two)).classes('w-32')
+    ui.button('Three', on_click=lambda: router.open(show_three)).classes('w-32')
+
+# this places the frame for the content which should be displayed
+router.frame().classes('w-full pt-8')
+
+
+ui.run()

+ 38 - 0
examples/single_page_app/router.py

@@ -0,0 +1,38 @@
+from typing import Callable
+
+from nicegui import background_tasks, ui
+from nicegui.dependencies import register_component
+from nicegui.element import Element
+
+register_component('router_frame', __file__, 'router_frame.js')
+
+
+class Router():
+
+    def __init__(self) -> None:
+        self.routes: dict[str, Callable] = {}
+        self.content: Element = None
+
+    def add(self, path: str):
+        def decorator(func):
+            self.routes[path] = func
+            return func
+        return decorator
+
+    def open(self, func: Callable):
+        path = {v: k for k, v in self.routes.items()}[func]
+        self.content.clear()
+
+        async def build():
+            with self.content:
+                cmd = f'history.pushState({{page: "{path}"}}, "", "{path}")'
+                print(cmd, flush=True)
+                await ui.run_javascript(cmd, respond=False)
+                await func()
+        background_tasks.create(build())
+
+    def frame(self):
+        self.content = ui.element('router_frame')
+        with self.content:
+            ui.label('Loading...').classes('text-2xl')
+        return self.content

+ 11 - 0
examples/single_page_app/router_frame.js

@@ -0,0 +1,11 @@
+export default {
+  template: `<div>Test</div>`,
+  mounted() {
+    window.addEventListener("popstate", (event) => {
+      if (event.state && event.state.page) {
+        console.log(event.state.page);
+      }
+    });
+  },
+  props: {},
+};