CodeZine(コードジン)

特集ページ一覧

新Vue.js「Vue 3」で便利に使えるさまざまな新機能を先取りで紹介

JavaScriptフレームワーク「Vue 3」の新機能紹介 第2回

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
目次

Composition APIだけではない、Vue 3の新機能(2)

コンポーネント内容を任意の場所に移動するTeleport

 Teleportは、コンポーネント内容の一部を、Webページ内の任意の場所に移動(テレポート)する機能です。モーダルダイアログやポップアップなど、コンポーネント外部に記述する必要があるHTML要素に、コンポーネント内容を反映する場合などに利用できます。図2のサンプルでは、コンポーネント内容の一部を、コンポーネント外(index.htmlに記述したHTML要素)にテレポートしています。

図2 Teleportのサンプル(p002-teleport)
図2 Teleportのサンプル(p002-teleport)

 コンポーネントの<template>部をリスト3に示します。(1)の通り、移動させる内容を<teleport>タグで囲み、to属性にテレポート先のCSSセレクター(ここでは「teleport-target」ID)を指定します。

[リスト3]Teleport元の記述(p002-teleport/src/components/TeleportFrom.vue)
<template>
  <div id="teleport-component">
    <h3>Teleport元(コンポーネント)</h3>
    <div>↓↓↓↓Teleport元↓↓↓↓</div>
    <teleport to="#teleport-target"> <!--(1)-->
      このテキストがTeleportされます
    </teleport>
    <div>↑↑↑↑Teleport元↑↑↑↑</div>
  </div>
</template>

 移動先ではリスト4(1)の通り、<teleport>タグのto属性に指定したCSSセレクターに対応するようにIDを設定しておきます。

[リスト4]Teleport先の記述(p002-teleport/public/index.html)
<h3>Teleport先(index.html)</h3>
<div>↓↓↓↓Teleport先↓↓↓↓</div>
<div id="teleport-target"></div> <!--(1)-->
<div>↑↑↑↑Teleport先↑↑↑↑</div>

 実行すると、リスト3(1)のteleportタグ内に記述された文言「このテキストがTeleportされます」が、リスト4(1)の部分に移動(テレポート)して表示されます。

<template>直下に複数のタグが記述できるFragment

 Vue 3ではFragment(複数のルートノードを持つコンポーネント)が利用できます。従来<template>の直下に記述できるタグは1つだけだったので、全体を単一の<div>タグで囲むのが一般的でしたが、例えばコンポーネントの上位に<ul>タグがあり、コンポーネント内に複数の<li>タグがあるといった構造を実現できませんでした。Vue 3ではリスト5の通り、複数タグを記述して対応できます。

[リスト5]Fragmentの記述(p003-fragment/src/components/ListElems.vue)
<template>
  <!-- このコンポーネントはulタグの中に表示される -->
  <li>iPhone 11</li>
  <li>Galaxy S20 5G</li>
  <li>AQUOS R5G</li>
</template>

コンポーネント準備中の表示を実現するSuspense

 Suspenseは、コンポーネント準備中の表示(ロード中など)を指定できる機能です。

図3 Suspenseのサンプル(p004-suspense)
図3 Suspenseのサンプル(p004-suspense)

 図3のサンプルの<template>部は、リスト6の通りです。<Suspense>タグ内に、コンポーネント(1)と、準備完了までの表示(2)に対応する2個の<template>を記述します。(1)には、準備完了までの時間が異なる(3秒と4秒)2個のコンポーネントが含まれますが、両方の準備が完了後(つまり4秒後)に表示が切り替わります。

[リスト6]Suspenseの記述(p004-suspense/src/App.vue)
<template>
  <Suspense>
    <template #default> <!--(1)-->
      <async-component1/> <!-- 3秒後に準備完了するコンポーネント -->
      <async-component2/> <!-- 4秒後に準備完了するコンポーネント -->
    </template>
    <template #fallback> <!--(2)-->
      全コンポーネントの準備完了を待っています...
    </template>
  </Suspense>
</template>

オブジェクトや配列のバインディング改善

 Vue 2では、配列要素の更新やオブジェクトのプロパティ追加/削除を画面に反映させるには、Vue.setやVue.deleteメソッドで間接的に操作する必要がありました。

[リスト7]Vue 2でのオブジェクトや配列のバインディング(p005-obj-array-binding-v2/src/App.vue)
// 配列要素の更新
// this.dataArray[0] = this.inputValue <- これでは画面に反映されない
Vue.set(this.dataArray, 0, this.inputValue)
// オブジェクトのプロパティ削除
// delete this.dataObj.name <- これでは画面に反映されない
Vue.delete(this.dataObj, 'name')

 Vue 3ではオブジェクトや配列のバインディングが改善され、配列要素の更新やオブジェクトのプロパティ追加/削除が、そのまま画面に反映されるようになりました。

[リスト8]Vue 3でのオブジェクトや配列のバインディング(p006-obj-array-binding-v3/src/App.vue)
// 配列要素の更新
state.dataArray[0] = state.inputValue;
// オブジェクトのプロパティ削除
delete state.dataObj.name

新しいアプリ開始処理createApp

 従来アプリ開始処理で利用していたVueオブジェクトに代わって、Vue 3ではcreateAppメソッドを利用するようになりました。

[リスト9]アプリ開始処理(p005-obj-array-binding-v2、p006-obj-array-binding-v3のsrc/main.js)
// 従来の開始処理
new Vue({
  render: h => h(App),
}).$mount('#app')
// Vue 3の開始処理
createApp(App).mount('#app')

フィルターの廃止

 フィルターは、変数をWebページに反映するときに内容を加工する機能ですが、メソッドで代用できることから、Vue 3では廃止されました。入力文字列を大文字に変換して表示する図4のサンプルで、フィルターとその代用方法を説明します。

図4 フィルターのサンプル(p007-filter-v2、p008-remove-filter-v3)
図4 フィルターのサンプル(p007-filter-v2、p008-remove-filter-v3)

 Vue 2でフィルターを利用した実装をリスト10に示します。

[リスト10]フィルターの利用例(p007-filter-v2/src/App.vue)
<template>
  <div>
    <input v-model="inputValue">
    <div>大文字:{{ inputValue | uppercase }}</div> <!--(1)-->
  </div>
</template>
<script>
export default {
  data() {
    return {
      inputValue: ''
    }
  },
  filters: {
    // 大文字に変換するフィルター ...(2)
    uppercase(value) {
      if (!value) return ''
      return value.toString().toUpperCase()
    }
  }
}
</script>

 フィルターの処理は、(2)のfiltersで実装します。ここでは大文字に変換するフィルターuppercaseを実装しています。このフィルターを利用して(1)で「{{ inputValue | uppercase }}」と記述することで、inputValueにuppercaseフィルターを適用して大文字にしています。

 同じ処理をVue 3で実装したものをリスト11に示します。

[リスト11]Vue 3でフィルターを代用する例(p008-remove-filter-v3/src/App.vue)
<template>
  <div>
    <input v-model="inputValue">
    <div>大文字:{{ uppercase(inputValue) }}</div> <!--(1)-->
  </div>
</template>
<script>
import { ref } from 'vue'
export default {
  setup() {
    const inputValue = ref('')
    // 大文字に変換するメソッド ...(2)
    function uppercase(value) {
      if (!value) return ''
      return value.toString().toUpperCase()
    }
    return {
      inputValue, uppercase
    }
  }
}
</script>

 (2)で実装した大文字変換メソッドuppercaseを、(1)で「{{ uppercase(inputValue) }}」と利用することで、inputValueを大文字にしています。

TypeScriptサポートの改善

 Vue 3はそれ自身がTypeScriptで開発されており、TypeScriptサポートが改善されています。TypeScript環境でComposition APIを利用する場合、リスト12の通りdefineComponentメソッドを利用すると、型推論が有効になります。

[リスト12]TypeScriptでComposition APIを利用する記述(p009-ts-reactive/src/components/Phones.vue)
export default defineComponent({
  setup() {
(略)
  }
})

 TypeScript環境では、reactiveやrefメソッドで記述するデータ変数に型を指定できます。reactiveの型指定はリスト13の通りです。reactiveメソッドの<>記述で、iOSとandroidにはstring配列、newIOSとnewAndroidにはstringの型を指定しています。

[リスト13]型を指定したreactive(p009-ts-reactive/src/components/Phones.vue)
const state = reactive<{
  iOS: Array<string>;
  newIOS: string;
  android: Array<string>;
  newAndroid: string;
  }>({
  iOS: ['iPhone 11'],
  newIOS: '',
  android: ['Galaxy S20 5G'],
  newAndroid: ''
})

 同じ型指定をrefで行う場合はリスト14の通り記述します。refメソッドの<>記述で、それぞれの型を指定しています。

[リスト14]型を指定したref(p010-ts-ref/src/components/Phones.vue)
const iOS = ref<Array<string>>(['iPhone 11'])
const newIOS = ref<string>('')
const android = ref<Array<string>>(['Galaxy S20 5G'])
const newAndroid = ref<string>('')

 なお、TypeScriptに対応したVue 3のプロジェクトをVue CLIで生成する方法は、p009-ts-reactive/p010-ts-refサンプルコードのREADME.mdを参照してください。

まとめ

 本記事では、Vue.jsの次期バージョン「Vue 3」に導入される、Composition API以外の新機能について説明しました。大小さまざまな新機能は、Vue.jsの使い勝手をより一層高めるものになっています。

参考資料

 



  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

バックナンバー

連載:JavaScriptフレームワーク「Vue 3」の新機能紹介
All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5