Skip to content

Refs

Refs let you access DOM elements from your component without manual querySelector calls. You declare them in the component config and access them via this.$refs.

Defining refs

Add ref names to the config.refs array. Each name corresponds to a data-ref attribute in your HTML.

Refs come in two forms:

  • Single ref (example: btn)
  • Multiple refs (example: items[])
js
class Component extends Base {
  static config = {
    name: 'Component',
    refs: [
      'btn', // single ref
      'items[]', // multiple ref with the `[]` suffix
    ],
  };
}

Single refs

To declare a single ref you must add it to the refs array like so:

js
import { Base } from '@studiometa/js-toolkit';

class Component extends Base {
  static config = {
    name: 'Component',
    refs: ['btn'], // Declare the ref
  };
}

Then in the HTML template you must add a data-ref attribute with the same name as above.

html
<div data-component="Component">
  <button data-ref="btn">Click me</button>
</div>

Multiple refs

If you want to iterate on multiple refs, you can append [] to the ref name. For example here data-ref="items[]" will yield an array of HTML elements.

Appending [] to a ref name will force the ref to an array even if there is only one occurrence.

js
class Component extends Base {
  static config = {
    name: 'Component',
    refs: ['items[]'],
  };
}

Then in the HTML template:

html
<div data-component="Component">
  <ul>
    <li data-ref="items[]">#1</li>
    <li data-ref="items[]">#2</li>
    <li data-ref="items[]">#3</li>
  </ul>
</div>

Naming convention

  • Ref names should be in camelCase
  • Ref names should help identify their usage: prefer openBtn over btn
  • Multiple refs names should be pluralized: prefer items[] over item[]

Using refs

Once refs are declared and added in the HTML template it becomes accessible via the corresponding instance property this.$refs.<name>.

html
<div data-component="Component">
  <button data-ref="btn">Click me</button>

  <ul>
    <li data-ref="items[]">#1</li>
    <li data-ref="items[]">#2</li>
    <li data-ref="items[]">#3</li>
  </ul>
</div>
js
class Component extends Base {
  static config = {
    name: 'Component',
    refs: ['btn', 'items[]'],
  };

  mounted() {
    this.$refs.btn; // <button data-ref="btn">Click me</button>
    this.$refs.items; // [<li data-ref="items[]">#1</li>, ...]
  }

  /**
   * Attaching a `click` event listener to the `btn` ref.
   */
  onBtnClick() {
    console.log('Button has been clicked!');
  }
}

Attaching events to a ref

Visit the Events page to learn how to handle events on refs.

Nested refs

By default, refs are resolved within the component's scope determined by the data-component attribute. In the following example, the parent component will only have one element in its this.$refs.items property.

html
<div data-component="Parent"> <─────────┐
  <div data-ref="items[]">direct</div> ─┘
  <div data-component="Child">
    <div data-ref="items[]">nested</div>
  </div>
</div>
js
import { Base } from '@studiometa/js-toolkit';
import Child from './Child.js';

class Parent extends Base {
  static config = {
    name: 'Parent',
    components: { Child },
    refs: ['items[]'],
  };

  mounted() {
    console.log(this.$refs.items.length);
    console.log(this.$refs.items[0]);
  }
}
js
// Logs
1
<div data-ref="items[]">direct</div>

If you need to access to nested refs, you can prefix the refs name with the component's name as defined in the static config property of the class.

html
<div data-component="Parent"> <─────────┐────────┐
  <div data-ref="items[]">direct</div> ─┘        │
  <div data-component="Child">                   │
    <div data-ref="Parent.items[]">nested</div> ─┘
  </div>
</div>
js
import { Base } from '@studiometa/js-toolkit';
import Child from './Child.js';

class Parent extends Base {
  static config = {
    name: 'Parent',
    components: { Child },
    refs: ['items[]'],
  };

  mounted() {
    console.log(this.$refs.items.length);
    console.log(this.$refs.items[0]);
    console.log(this.$refs.items[1]);
  }
}
js
// Logs
2
<div data-ref="items[]">direct</div>
<div data-ref="Parent.items[]">nested</div>

Nested refs and nested components

The resolution scope of nested refs will be limited in case of nested components.

html
<div data-component="Parent"> <─────────┐
  <div data-ref="items[]">direct</div> ─┘
  <div data-component="Child">
    <div data-component="Parent"> <────────────────┐
      <div data-ref="Parent.items[]">nested</div> ─┘
    </div>
  </div>
</div>

See also: data-ref · Configuration — refs · $refs

MIT Licensed