Properties

Available in all directive expressions:

  • $el: The current element the directive is bound to. Available in all directives (lu-on, lu-bind, lu-effect, etc.).
  • $root: The root element of the lu-scope component.
  • $refs: A collection of elements marked with the ref directive.
  • $nextTick: Function to defer a callback until after the next DOM update cycle.
  • $data: The current scope object itself.

Names in an expression resolve in this order: local bindings the expression introduces (arrow parameters and let/const/var), then the scope, then $data and $el, and finally the globals the engine allows. A scope property named $el or $data therefore shadows the built-in.

$el

Represents the current element that the directive is bound to.

Usage

$el is available in all directive expressions, including event handlers (@click), lu-bind, lu-effect, and more.

In Event Handlers

html
<button @click="console.log($el)">Log Me</button>

In lu-effect

html
<div lu-scope="{ msg: 'hello' }">
  <div lu-effect="$el.textContent = msg"></div>
</div>

Auto-focus Input

html
<input @lune:mounted="$el.focus()" />

Integrating 3rd Party Libraries

Templates cannot reach arbitrary application globals, so put the library in the app data:

js
import Pikaday from "pikaday";

createApp({ Pikaday }).mount();
html
<div @lune:mounted="new Pikaday({ field: $el })">
  <input type="text" />
</div>

Or register it once with allowGlobals(), which makes it available to every template (see Security):

js
import { allowGlobals } from "lune-js";
import Pikaday from "pikaday";

allowGlobals({ Pikaday });

Difference from standard Vue

In standard Vue, $el typically refers to the component's root element. In Lune, $el always points to the current element the directive is on.

$nextTick

A utility to wait for the next DOM update cycle.

Usage

html
<div lu-scope="{ count: 0 }">
  <div ref="counter">{{ count }}</div>
  <button
    @click="
    count++;
    $nextTick(() => {
      console.log($refs.counter.textContent) // logs updated value
    })
  "
  >
    Increment
  </button>
</div>

Details

When you mutate state in Lune, the DOM updates asynchronously. If you need to perform an operation that depends on the updated DOM, use $nextTick.

Async Update Queue

Lune buffers all state changes and flushes them together in the next "tick". This ensures that you don't trigger unnecessary re-renders if you change the same data multiple times.

js
count = 1;
count = 2;
count = 3;
// DOM updates only once with 3

$data

The current scope object — the same object your expressions read from. It is useful for handing the whole scope to a function at once, or for reading a property whose name is computed.

html
<div lu-scope="{ count: 0, key: 'count' }">
  <p>{{ $data[key] }}</p>
  <button @click="console.log($data)">Log Scope</button>
</div>

$refs

An object holding DOM elements that have the ref attribute registered.

Usage

html
<div lu-scope>
  <input ref="input" />
  <button @click="$refs.input.focus()">Focus Input</button>
</div>

Details

Refs are populated after the component is mounted. They are not reactive, so you should not use them in templates for data binding.

$refs always holds the DOM element, never a scope object. A ref on an element that also carries lu-scope is registered both in that element's own $refs and in its parent's, so the surrounding scope can reach it too.

$root

The root element of the current component (the element with lu-scope). This is set automatically when lu-scope initializes.

Usage

html
<div lu-scope>
  <button @click="console.log($root)">Log Component Root</button>
</div>