BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Vue.js 2.6 "Macross" Released with Improved Slots Syntax

Vue.js 2.6 "Macross" Released with Improved Slots Syntax

On February 4th, Evan You announced the next minor release of Vue. Vue 2.6 (code-named Macross) contains new features, improvements and bug fixes. Slots get a streamlined syntax, and directives accept dynamic JavaScript expressions as arguments. Developers can now design generic Vue components with a greater flexibility to compose their children components.

Vue 2.6 introduces a revamped unified syntax for slots. The Vue slot documentation provides the example of a <base-layout> component with three slots (a default slot, a header slot, and a footer slot):

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

The slots declared in the <base-layout> component will be filled with the matching content as found in the children components of the <base-layout> component. Children components may indicate slot content with a new v-slot directive:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

The rendered HTML will be:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

Vue 2.6 also unifies normal and scoped slots with the same v-slot directive syntax. Scoped slots are slots which are passed parameters (also called properties or props) from their surrounding context. The Vue slot documentation gives the <current-user> component example, which passes the user variable to its default slot, and displays the last name of the user as fallback content:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

The <current-user> component can then be used with a child component which fills in the default slot with the user's first name like this:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

The user variable from the <current-user> component has then been bound to the user property of the slotProps variable accessible in the template child component.

A commonly occurring use case is when a parent component only needs a default slot and no named slot. In that specific case, Vue 2.6 optionally allows an even more simplified syntax. The v-slot directive moves to the component tag level, and the default attribute may get omitted.

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName || 'Guest' }}
  </template>
</current-user>

becomes, using standard JavaScript expressions:

<current-user v-slot="{ user = { firstName: 'Guest' } }">
  {{ user.firstName }}
</current-user>

Vue 2.6 also introduces dynamic directive arguments. It is now possible to use a JavaScript expression in a directive argument. The corresponding RFC gives the following examples:

<!-- v-bind with dynamic key -->
<div v-bind:[key]="value"></div>

<!-- v-bind shorthand with dynamic key -->
<div :[key]="value"></div>

<!-- v-on with dynamic event -->
<div v-on:[event]="handler"></div>

<!-- v-on shorthand with dynamic event -->
<div @[event]="handler"></div>

<!-- v-slot with dynamic name -->
<foo>
  <template v-slot:[name]>
    Hello
  </template>
</foo>

Here, key, event and name will be dynamically evaluated as a JavaScript expression, and their evaluated value will be used as the final value for the argument.

The net result of the Vue 2.6 new features and improvements is a more expressive template syntax that empowers Vue developers to write more generic, reusable, and customizable components within the template language. Components' users thus less likely need resorting to the full power of JavaScript through Vue's render functions. For instance, the vue-virtual-scroller library proposes components which abstract the behavior of displaying children components only as needed. Those components largely rely on scoped slots to provide a friendly and intuitive interface.

Vue.js is available under the MIT open-source license. Contributions are welcome via the Vue.js GitHub package and should follow the Vue.js [contribution guidelines].

Rate this Article

Adoption
Style

BT