1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use crateVNode;
/// A UI component with lifecycle hooks, similar to Vue 3's Options API.
///
/// # Lifecycle
///
/// 1. **`init()`** — called once before the first render. Initialize Signals,
/// Computed values, and Effects here. Equivalent to Vue 3's `setup()` or
/// the `data()` option.
///
/// 2. **`render()`** — called to produce the VNode tree. Called on initial
/// mount and on every subsequent update. This is the component's template.
///
/// 3. **`mounted()`** — called after the component's DOM nodes have been
/// inserted into the document. Use this to access DOM properties,
/// integrate with third-party JS libraries, or start timers.
/// Equivalent to Vue 3's `onMounted()`.
///
/// 4. **`should_update()`** — called before each re-render. Return `false`
/// to skip the update entirely (useful for optimization).
///
/// # Example
///
/// ```ignore
/// use rue_core::*;
/// use rue_macros::html;
///
/// struct Counter {
/// count: Signal<i32>,
/// }
///
/// impl Component for Counter {
/// fn init(&mut self) {
/// self.count = signal(0);
/// }
///
/// fn render(&self) -> VNode {
/// let value = self.count.get_clone();
/// html! {
/// <div>
/// <p>{"Count: "}{value}</p>
/// <button on:click={move |_| {
/// self.count.set(self.count.get_clone() + 1);
/// }}>{"+"}</button>
/// </div>
/// }
/// }
/// }
/// ```