# Components and Lifecycle Events
In Lune, components are simplified compared to standard Vue. They are primarily functions that return a scope object.
## Function Components
Reusable scope logic can be created with functions:
```js
function Counter(props) {
return {
count: props.initialCount,
inc() {
this.count++;
},
onMounted() {
console.log(`I'm mounted!`);
}
};
}
createApp({
Counter
}).mount();
```
### Usage
Use the function in `lu-scope` to instantiate the component:
```html
{{ count }}
{{ count }}
```
> [!NOTE]
> Lune does **not** have automatic lifecycle hooks like `mounted()` or `setup()`. To run code when a component is mounted, define a method in your scope and wire it up manually using `@lune:mounted="methodName"`. See [Lifecycle Events](#lifecycle-events) for details.
## Components with Template
If you want to reuse a piece of template, you can provide a special `$template` key on the scope object. The value can be an ID selector to a `` element:
```js
function Counter(props) {
return {
$template: "#counter-template",
count: props.initialCount,
inc() {
this.count++;
}
};
}
```
```html
My count is {{ count }}
```
The `` approach is recommended over inline strings because it is more efficient to clone from a native template element.
## Organizing Code
For larger projects, it's best to keep your component logic in separate JavaScript files.
`components/Counter.js`:
```js
export default function Counter(props) {
return {
count: props.initialCount || 0,
inc() {
this.count++;
},
dec() {
this.count--;
}
};
}
```
`index.html`:
```html
...
```
## Lifecycle Events
Lune provides special lifecycle events that you can listen to on any element:
- `@lune:mounted`: Fired when the element is mounted and directives are initialized.
- `@lune:unmounted`: Fired when the element is unmounted (e.g., via `lu-if`).
### Usage
```html
I am visible
```
## Practical Use Cases
### Auto-focus Input
```html
```
### Integrating 3rd Party Libraries
You can use `@lune:mounted` to initialize jQuery plugins or other libraries on the element. A library
is not reachable from a template just because it is a global — put it in the app data, or register it
with [`allowGlobals`](/advanced/security#application-globals):
```js
import Pikaday from "pikaday";
createApp({ Pikaday }).mount();
```
```html
```
A component function is the other way around it, since the function body is ordinary JavaScript:
```js
function DatePicker() {
return {
init($el) {
new Pikaday({ field: $el });
}
};
}
createApp({ DatePicker }).mount();
```
```html
```
### Cleanup
Use `@lune:unmounted` to clean up event listeners or timers to prevent memory leaks.
## Lifecycle Diagram
Here is a visualization of the component lifecycle:
```mermaid
graph TD
A[lu-scope detected] --> B{Component Init}
B --> C[Created]
C --> D[Mounted]
D --> E{State Change}
E --> F[Updated]
F --> D
D --> G[Element Removed]
G --> H[Unmounted]
```
> [!NOTE]
> `lu-effect` watchers are automatically disposed of when the component is unmounted.