Add browser behavior
Some interactions should respond at once, without asking the server: a counter, a toggle, a menu that opens. So far everything you built finishes in Python. In this step you add behavior that runs in the browser, with no request and no page reload.
Citry uses Vue for browser behavior. You write Vue attributes in the template, and Python gives each component its starting browser data.
Build the counters
Save this example as click_counters.py:
from citry import Component
class ClickCounter(Component):
class Kwargs:
name: str
class Slots:
pass
def js_data(self, kwargs: Kwargs, slots: Slots):
return {"name": kwargs.name, "count": 0}
template = """
<button
class="counter"
type="button"
@click="count = count + 1"
>
<span class="counter__name" v-text="name"></span>
clicked
<span class="counter__count" v-text="count"></span>
times
</button>
"""
class CounterPage(Component):
class Kwargs:
pass
class Slots:
pass
template = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Component data</title>
</head>
<body>
<c-ClickCounter name="Ada" />
<c-ClickCounter name="Grace" />
</body>
</html>
"""
page = CounterPage()
if __name__ == "__main__":
print(page)
page
Create the page and open it in a browser:
python click_counters.py > click_counters.html
Both buttons start at zero. Click Ada's button: Ada changes to one, and Grace stays at zero.
Update on click
Two Vue attributes, called directives, connect the button to its data:
@click="count = count + 1"adds one tocountwhen the button is clicked.v-textwrites the current name and count into their spans.
When Citry sees Vue directives in a template, it adds its browser code to the page. You do not need a separate JavaScript entry file or Vue setup.
Set starting data
js_data() returns the data the component starts with in the browser:
def js_data(self, kwargs: Kwargs, slots: Slots):
return {"name": kwargs.name, "count": 0}
The values must be JSON-serializable. Vue watches each top-level key, and when one changes, it updates the parts of the page that show it. Each counter gets its own copy, so clicking Ada cannot change Grace.
Add Vue options
When a component needs more than data, such as methods, props, emitted events, or code that runs when it first appears on the page, pass Vue options to $component in the component's js string. The js string holds the component's JavaScript, the way css holds its CSS:
$component({
methods: {
reset() {
this.count = 0;
},
},
});
The next step uses this to connect two components. Component options documents everything $component accepts, and Vue in templates covers the template syntax.