Open wbijker opened 9 months ago
Design with lifecycle events
<?php
class Counter extends Component {
counter = 0;
function buttonClicked() {
$this->counter++;
}
override function saveState(): array {
// run after each action performed on the page
// default implementation is to persist all members of this page
}
override function restoreState($saved: array) {
// run just before any action on the page
// does not run on the first render
// default restore all members of this page
}
override function initialize() {
// run on every render before anything
$this->counter = intVal($this->request->query("counter", 0));
}
overide function created() {
// run on the first render of the page
}
overide function destroyed() {
// after this component has been removed
}
override function render(): HtmlResult {
// use the functional compositional way to create html
return div(
new HtmlAttr("v-app", {"selectIndex: 0"}),
class("mx-auto bg-gray-100"),
button(
text("Click me"),
onClick($this->buttonClicked)
),
span(
show($this->visible),
new HtmlAttr("v-show", "selectIndex == 1"),
text("The current counter is ".$this->counter)
),
button(
new HtmlAttr("@click", "selectedIndex = 1")
text("Toggle")
)
)
}
}
function show($condition): HtmlAttr {
return class($condition ? "block" : "none");
}
?>
register CounterPage in entry point (routes, controllers)
events: state, event cycles
handle events with parameters
JS invoke phase 2
events can be member functions, but also can invoke JS functions.
each component can also skip some JS, to perform JS clientside functions.
$diff = diff($old, $new);
render $diff to fontend to apply the changes.
render multiple instances of Components.
<?php
class App extends Component {
private $counter1 = new Counter();
private $counter2 = new Counter();
function setBoth() {
// inperative handler
$counter1->set(12);
$counter2->set(12);
}
override function render(): HtmlResult {
return div(
class("h-screen w-full bg-red-200"),
button(
text("Set both counters"),
onClick(&$this->setBoth)
),
div(
$counter1,
$counter2
)
)
}
}
renderApp(new App())
Create two base classes. ViewComponent - a component that does not carry any state and it basically a function that will return a HtmlTemplateNode; StateComponent - a component that can dynamically read and write state.