Bladeren bron

add example for creating custom vue components

Falko Schindler 2 jaren geleden
bovenliggende
commit
997fbf3813

+ 1 - 1
api_docs_and_examples.py

@@ -759,7 +759,7 @@ You can call `ui.run()` with optional arguments:
 - `uvicorn_reload_includes`: string with comma-separated list of glob-patterns which trigger reload on modification (default: `'.py'`)
 - `uvicorn_reload_excludes`: string with comma-separated list of glob-patterns which should be ignored for reload (default: `'.*, .py[cod], .sw.*, ~*'`)
 - `exclude`: comma-separated string to exclude elements (with corresponding JavaScript libraries) to save bandwidth
-  (possible entries: chart, colors, custom_example, interactive_image, keyboard, log, joystick, scene, table)
+  (possible entries: chart, colors, interactive_image, keyboard, log, joystick, scene, table)
 
 The environment variables `HOST` and `PORT` can also be used to configure NiceGUI.
 

+ 23 - 0
examples/custom_vue_component/counter.js

@@ -0,0 +1,23 @@
+Vue.component("counter", {
+  template: `
+  <button v-bind:id="jp_props.id" v-on:click="handle_click">
+    <strong>{{jp_props.options.title}}: {{jp_props.options.value}}</strong>
+  </button>`,
+  methods: {
+    handle_click() {
+      this.$props.jp_props.options.value += 1;
+      const event = {
+        event_type: "onChange",
+        vue_type: this.$props.jp_props.vue_type,
+        id: this.$props.jp_props.id,
+        page_id: page_id,
+        websocket_id: websocket_id,
+        value: this.$props.jp_props.options.value,
+      };
+      send_to_server(event, "event");
+    },
+  },
+  props: {
+    jp_props: Object,
+  },
+});

+ 33 - 0
examples/custom_vue_component/counter.py

@@ -0,0 +1,33 @@
+from typing import Callable, Optional
+
+from addict import Dict
+from nicegui.elements.custom_view import CustomView
+from nicegui.elements.element import Element
+from nicegui.routes import add_dependencies
+
+add_dependencies(__file__)  # automatically serve the .js file with the same name
+
+
+class CounterView(CustomView):
+
+    def __init__(self, title: str, on_change: Optional[Callable]) -> None:
+        super().__init__('counter', title=title, value=0)  # pass props to the Vue component
+
+        self.on_change = on_change
+        self.allowed_events = ['onChange']
+        self.initialize(temp=False, onChange=self.handle_change)
+
+    def handle_change(self, msg: Dict) -> None:
+        if self.on_change is not None:
+            self.on_change(msg.value)
+        return False  # avoid JustPy's page update
+
+
+class Counter(Element):
+
+    def __init__(self, title: str, *, on_change: Optional[Callable] = None) -> None:
+        super().__init__(CounterView(title, on_change))
+
+    def reset(self) -> None:
+        self.view.options.value = 0
+        self.update()  # update the view after changing the counter value

+ 19 - 0
examples/custom_vue_component/main.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+from nicegui import ui
+
+from counter import Counter
+
+ui.markdown('''
+#### Try the new click counter!
+
+Click to increment its value.
+''')
+with ui.card():
+    counter = Counter('Clicks', on_change=lambda value: message.set_text(f'The value changed to {value}.'))
+
+
+ui.button('Reset', on_click=lambda: counter.reset()).props('small outline')
+
+message = ui.label()
+
+ui.run()

+ 0 - 24
nicegui/elements/custom_example.js

@@ -1,24 +0,0 @@
-Vue.component("custom_example", {
-  template: `
-  <button v-bind:id="jp_props.id">
-    <strong>Custom example component</strong><br/>
-    Value = {{jp_props.options.value}}<br/>
-    Click to add 1!
-    </button>`,
-  mounted() {
-    document.getElementById(this.$props.jp_props.id).onclick = () => {
-      const event = {
-        event_type: "onAdd",
-        vue_type: this.$props.jp_props.vue_type,
-        id: this.$props.jp_props.id,
-        page_id: page_id,
-        websocket_id: websocket_id,
-        number: 1,
-      };
-      send_to_server(event, "event");
-    };
-  },
-  props: {
-    jp_props: Object,
-  },
-});

+ 0 - 31
nicegui/elements/custom_example.py

@@ -1,31 +0,0 @@
-from ..routes import add_dependencies
-from .custom_view import CustomView
-from .element import Element
-
-add_dependencies(__file__)
-
-
-class CustomExampleView(CustomView):
-
-    def __init__(self, on_change):
-        super().__init__('custom_example', value=0)
-
-        self.on_change = on_change
-        self.allowed_events = ['onAdd']
-        self.initialize(temp=False, onAdd=self.handle_add)
-
-    def handle_add(self, msg):
-        self.options.value += msg.number
-        if self.on_change is not None:
-            return self.on_change(self.options.value)
-        return False
-
-
-class CustomExample(Element):
-
-    def __init__(self, *, on_change=None):
-        super().__init__(CustomExampleView(on_change))
-
-    def add(self, number: str):
-        self.view.options.value += number
-        self.view.on_change(self.view.options.value)

+ 0 - 2
nicegui/routes.py

@@ -105,8 +105,6 @@ def create_exclude_routes() -> None:
         add_route(None, Route('/templates/local/highcharts.js', void))
     if 'colors' in globals.config.excludes:
         add_route(None, Route('/colors.js', void))
-    if 'custom_example' in globals.config.excludes:
-        add_route(None, Route('/custom_example.js', void))
     if 'interactive_image' in globals.config.excludes:
         add_route(None, Route('/interactive_image.js', void))
     if 'keyboard' in globals.config.excludes:

+ 0 - 1
nicegui/ui.py

@@ -17,7 +17,6 @@ class Ui:
     from .elements.color_picker import ColorPicker as color_picker
     from .elements.colors import Colors as colors
     from .elements.column import Column as column
-    from .elements.custom_example import CustomExample as custom_example
     from .elements.dialog import Dialog as dialog
     from .elements.expansion import Expansion as expansion
     from .elements.html import Html as html