2019.02.11

Vue 2.6 で追加された新しい機能とシンタックス


2月5日に Vue の新バージョン 2.6 がリリースされました。この記事では、バージョン 2.6 で追加された新たなシンタックスと新機能をピックアップして紹介します。

新しいスロット構文

v-slot

まずは slot の新しいシンタックスです。v-slot ディレクティブが追加されました。

ver. 2.5 までは slot の名前を指定する際に以下のように記述していました。

2.5
<card>
  <h3 slot="title">レッサーパンダ</h3>
  <p slot="content">
    レッサーパンダ(Ailurus fulgens)は、哺乳綱食肉目レッサーパンダ科レッサーパンダ属に分類される食肉類。本種のみでレッサーパンダ属を構成する。
  </p>
</card>

ver. 2.6 では v-slot:スロット名 というディレクティブでスロットの名前を指定します。

2.6
<card>
  <template v-slot:title>
    <h3>レッサーパンダ</h3>
  </template>
  <template v-slot:content>
    <p>
      レッサーパンダ(Ailurus fulgens)は、哺乳綱食肉目レッサーパンダ科レッサーパンダ属に分類される食肉類。本種のみでレッサーパンダ属を構成する。
    </p>
  </template>
</card>

v-slot<template> 要素にしか適用できませんので注意しましょう。

さらに v-slot:スロット名 には #スロット名 という省略記法も用意されています。

2.6
<card>
  <template #title>
    <h3>レッサーパンダ</h3>
  </template>
  <template #content>
    <p>
      レッサーパンダ(Ailurus fulgens)は、哺乳綱食肉目レッサーパンダ科レッサーパンダ属に分類される食肉類。本種のみでレッサーパンダ属を構成する。
    </p>
  </template>
</card>

スコープ付きスロット

スコープ付きスロットにも上記の記法が利用できます。

このようなコンポーネントがあったとして...

todo-list
<ul>
  <li v-for="todo in todos" :key="todo.id">
    <slot :todo="todo">
      {{ todo.text }}
    </slot>
  </li>
</ul>

ver. 2.5 までは以下のように slot-scope 属性を使って子コンポーネントのスロットに渡されたプロパティにアクセスしていました。

2.5
<todo-list :todos="todos">
  <template slot="default" slot-scope="slotProps">
    Task : {{ slotProps.todo.text }}
  </template>
</todo-list>

ver. 2.6 では v-slot ディレクティブの引数として記述します。

2.6
<todo-list :todos="todos">
  <template v-slot:default="slotProps">
    Task : {{ slotProps.todo.text }}
  </template>
</todo-list>

<!-- または -->
<todo-list :todos="todos">
  <!-- 省略記法 -->
  <template #default="slotProps">
    Task : {{ slotProps.todo.text }}
  </template>
</todo-list>

ver. 2.5 までは slot 属性と slot-scope 属性に別れていた記法が、ver. 2.6 からは v-slot に統一されたのでシンタックスがスッキリしたと思います。

非同期エラーのキャプチャ

ライフサイクルフック errorCaptured およびグローバルフック errorHandler で非同期処理のエラーを捕捉できるようになりました。

たとえば子コンポーネントでの非同期処理でエラーがあった場合...

子コンポーネント
async mounted () {
  const response = await axios.get('/api/...')
}

親コンポーネントの errorCaptured で捕捉することができます。

親コンポーネント
errorCaptured (err, vm, info) {
  // エラー画面やダイアログを表示するなど
}

ver. 2.5 までは非同期エラーは errorCapturederrorHandler は捕捉できなかったので、これは便利ですね!SPA の開発では API への非同期通信は必須ですから、通信エラー処理をまとめる書き方の可能性が広がったという意味で、2.6 の目玉機能なのではないでしょうか。

リアクティブなグローバルオブジェクト

observable メソッドによってリアクティブなオブジェクトを作成できるようになりました。

const counterState = Vue.observable({
  count: 0
})
<button @click="counterState.count += 1">
  {{ counterState.count }}
</button>

リアクティブというのは、ざっくり言うと「あっちで値を変えたらこっちの表示も追随して変わる」ということですね。この機能は個人的には使いどころがまだ思いついていませんが、Vuex より軽量な状態管理には使えるかもしれません。

動的なディレクティブ

ディレクティブの名前を動的に指定するための構文が追加されました。

custom-button
<button v-on:[event]="handler"></button>
<button @[event]="handler"></button>
<custom-button event="click"></custom-button>

上記のように、[] でディレクティブを動的に指定できます。

v-bindv-slot も同様です。

<div v-bind:[attr]="value"></div>
<div :[attr]="value"></div>

<my-component>
  <template v-slot:[slotName]>
    Dynamic slot name
  </template>
</my-component>

頭の片隅に入れておいて、いざという時に使えるようにしておきたいですね。


以上、Vue 2.6 で追加された新たなシンタックスと機能を紹介しました。