banner
bayi-95

bayi-95

"探索"本身就是一件很有趣的事情 :)
github

Vue3 技術共有

Vue 3 の背景と意義#

フロントエンド技術の急速な発展に伴い、開発者たちはフレームワークに対してより高い要求を突きつけています:より高いパフォーマンスとより良い開発体験を持ち、さらに多くの機能をサポートする必要があります。このような背景の中で、より優れた Vue 3 が誕生しました:

1. より良いパフォーマンス:Vue 3 は、リアクティブシステムの再構築とテンプレートコンパイラの最適化を採用し、パフォーマンスが Vue 2 に比べて大幅に向上しました。例えば、レンダリング性能は約 1.5-3 倍向上しました。

2. より良い開発体験:Vue 3 は、構文、型推論、ライフサイクルなどの面で改善を行い、より良い開発体験を提供します。また、Composition API などの新機能を導入し、コードとロジックをより柔軟に整理できるようになりました。

3. より多くの機能:Vue 3 は、ポータル、テレポート、サスペンスなどの新機能を追加し、コンポーネントの再利用や非同期レンダリングなどのシナリオにおいて、より良い解決策を提供します。

Vue 2 の問題点#

Vue 2 は非常に優れた人気のあるフロントエンド JavaScript フレームワークですが、以下のような問題も存在します:

1. 可読性と保守性の低さ:Vue 2 は Options API を使用してコンポーネントを定義し、関連するロジックが異なるライフサイクル関数に散らばっているため、コンポーネントのロジックが読みづらく、保守が難しいです。特に複雑なコンポーネントの場合、開発、デバッグ、テスト時にチームに大きな困難をもたらします。

2. 静的型検査の問題:Vue 2 は静的型検査をネイティブにサポートしていないため、プロジェクトの開発と保守の過程で大きな問題を引き起こします。TypeScript や Flow などのサードパーティツールを使用してこの問題を解決することは可能ですが、デプロイ、学習、使用において相当な追加投資が必要になる場合があります。

3. パフォーマンスの問題:Vue 2 の仮想 DOM は、大量のデータ変更を行う場合に一定のパフォーマンス問題が発生します。また、Vue 2 はテンプレートコンパイラに欠陥があり、ある程度フレームワークのパフォーマンスを低下させています。

Vue 3 の目標と利点#

1. より高いパフォーマンス:Vue 3 は、リアクティブシステムと仮想 DOM の実装を再構築し、全体的なパフォーマンスを向上させました。例えば、レンダリング性能は約 1.5-3 倍向上し、メモリ使用量も軽量化されています。

2. より良い TypeScript サポート:Vue 3 は、より充実した TypeScript サポートを提供し、型チェックを通じてプログラム内のエラーや問題を捕捉し、コードの堅牢性と可読性を向上させます。また、TypeScript と Composition API の組み合わせにより、より良いコードの整理と保守性が実現されます。

3. より柔軟なコンポーネント開発方式:Vue 3 は、Vue 2 に存在するオプションベースの API を廃止し、基本的に Options API を置き換えることができる Composition API を導入しました。これにより、開発者は関数ベースでコンポーネントを開発する方法がより柔軟かつ効率的になります。

4. より良い開発ツールのサポート:Vue 3 は、関連する DevTools やドキュメントを全面的に更新しました。例えば、Vuex や VueRouter などの面でもアップグレードが行われています。

5. より小さなパッケージサイズ:Vue 3 は、いくつかの古くなった、廃止された API を削除し、パッケージ後のサイズを小さくし、他のプロジェクトの構築を容易にしました。

要するに、Vue 3 は設計に重点を置き、ほぼすべての面で明確な改善が見られます。Vue 3 は、より多くの機能を提供し、型安全性を保証し、さらにより速いレンダリング速度より少ないメモリ使用量といった追加の利点を持っています。

 


 

Vue 3 の新機能概要#

リアクティブシステムの改善#

Vue 2 では、リアクティブシステムは Object.defineProperty を使用してプロパティをハイジャックすることで、データとビュー間の双方向バインディングを実現していました。しかし、この実装方法には明らかな欠点があります:配列の変化を監視できない、getter/setter の処理が一部の状況で遅い、深いネストされたオブジェクトの監視ができないなどです。

そのため、Vue 3 では Proxy API を使用して Object.defineProperty を置き換え、リアクティブデータバインディングを実現しました。前者と比較して、Proxy はすべてのタイプのプロパティ変更を監視でき、言語のランタイム制限に依存せず、より良いパフォーマンスを発揮します。また、Proxy は直接代入操作をインターセプトできるため、Traps のような問題を回避できます。さらに、Proxy は Map、Set、Weakmap、Weakset をサポートしています。

Vue 3 では、Vue 2 の watch メソッドと $set/delete メソッドが廃止され、前者は watchEffect と watch に置き換えられ、後者はネイティブ JavaScript の API(例えば Array#splice)を使用してリアクティブオブジェクトを操作できるようになりました。

より速いレンダリング性能#

1. コンパイル時最適化(Compile-time Optimization):Vue 3 は、コンパイル段階のテンプレート静的分析を通じて、実行時により最適化されたコードを生成し、パフォーマンスを向上させます。例えば:Hoist Static、Cache Handlers。

2. より速い内部アルゴリズム(Faster Internal Algorithm):Vue 3 は仮想 DOM レンダリングエンジンを再構築し、ホイスト技術を使用して、仮想 DOM 更新プロセスにおける冗長な操作を大幅に削減しました。また、パッチプロセスの負担を軽減するために、通常は複雑なネストを避けたり、動的キーを使用したり、不必要な計算操作を避けたりします。

3. 関数型コンポーネント指向設計(Functional Component-oriented Design):Vue 3 は関数型コンポーネントのサポートをより充実させ、ネイティブにし、コンパイル後に生成されるレンダリング関数も Vue 2 よりも簡潔になり、一部の小さなスクリプトを削減しました。

より小さなパッケージサイズ#

主に以下の方法で実現されています:

1. より細かいモジュール化:コアライブラリを複数の小さなモジュールに分割し、ユーザーは必要なモジュールだけをインポートすればよく、全体のライブラリをインポートする必要がなくなり、パッケージサイズが減少します。

2. Tree-shaking サポート:Vue 3 は、現代のバンドルツールの依存関係分析メカニズムに対応しており、未使用のコードを自動的に削除することで、バンドルファイルのサイズを最小化します。

3. 不要な機能と API の削除:Vue 3 は、Vue 2 においてあまり使用されない、またはほとんど使用されない機能や API を削除しました。例えば、インラインテンプレート、フィルターなどです。

4. ネイティブ ES モジュールのエクスポート、および純粋関数の封装により、ランタイムデータチェックを回避します。

より良い TypeScript サポート#

TypeScript サポートにおいて顕著な改善があり、主に以下の点で表れています:

1. Composition API:Vue 3 に導入された Composition API は、TypeScript の型推論をより良くサポートします。Composition API を使用してコンポーネントを記述する際、ジェネリックやインターフェースなどを使用することで、TypeScript がより便利に型チェックを行う手助けをします。

2. 内蔵定義ファイル:Vue 3 のソースコードには、充実した TypeScript 定義ファイルが付属しており、また Vue 2 の DefinitelyTyped 上の型定義ファイルもサポートされています。@vue/runtime-core パッケージを直接インストールすることで、インポートして使用できます。

3. 開発ツールチェーンの整備:Vue CLI や Vue Devtools などのツールも TypeScript に対して良好なサポートを提供し、自動的に対応する TypeScript 型定義ファイルを生成し、コード編集やデバッグを容易にします。

4. コンポーネント Props の型検証:Vue 3 では、Prop の型を設定したり、TypeScript のインターフェースや型などの構文を使用して Prop の型検証を行ったりできます。

Composition API#

Vue3 の Composition API は、オプションオブジェクトではなく関数に基づいてコンポーネントコードを整理する方法で、コンポーネント内のロジックコードを整理するためのより細かいメソッドを提供します。主な特徴は以下の通りです:

1. reactive と computed:reactive と computed を使用して、リアクティブデータを作成し、計算プロパティを定義できます。

2. ライフサイクルフック:onMounted、onUpdated などのフック関数を使用して、Vue2 のライフサイクル関数の代わりにします。

3. ref:変数をラップするツールで、リアクティブにすることができます。例えば、input 要素の value 属性などです。

4. watch と watchEffect:watch は特定のリアクティブデータの変化を監視し、対応する操作を実行します。watchEffect は依存関係を自動的にリアクティブに追跡します。

5. provide と inject:provide と inject の組み合わせを使用することで、階層を超えてデータを渡すことができます。

より良いアクセシビリティサポート#

アクセシビリティに関しても、以下の改善が行われています:

  1. カスタムアクセシブルランドマーク:Vue3 は、アクセシブルランドマーク機能の数を拡大し、意味的な構造を提供し、検索エンジンやブラウザの処理を改善し、障害者に配慮しています。

  2. 新しい v-model API:Vue3 の v-model API では、input や textarea でカスタムの setter バリデーターを受け入れることができ、コンポーネントにバインドされたモデルの値が指定されたルールに従うことを保証します。これにより、入力データの品質とコード上のエラー捕捉が大いに助けられます。

  3. 改善された ARIA 要素マークアップのアクセシビリティ:Vue3 は ARIA 要素マークアップに対して、より簡単で直感的な方法を提供し、現代の標準をサポートし、他の意味的な構造とより良く接続し、スクリーンリーダーの解析をより良くカスタマイズします。

  4. より良い TypeScript 型安全性:TypeScript 型により、多くの型エラーを回避し、コードの可読性と保守性を向上させ、プロパティやメソッドのドキュメントをより簡単に見つけることができます。

  5. SSR モードでのアクセシビリティのサポート:Vue2 と比較して、Vue3 はサーバーサイドレンダリング(SSR)において多くの重要な改善を行いました。例えば、クライアントとサーバー間の効率的なコード分割方法や、より良いヘッダー応答処理を提供しています。

 


 

リアクティブシステムの改善#

Proxy 代理の使用#

主な技術は、ECMAScript 6 の Proxy オブジェクトを利用することです。代理オブジェクトを使用することで、プロパティの代入や取得などの関連操作をインターセプトでき、特定のシーンでより良いパフォーマンス最適化を提供できます。Proxy を使用した Vue3 のリアクティブシステムの改善は以下の通りです:

  1. 普通の JavaScript オブジェクトを直接監視:Vue3 は、普通の JavaScript オブジェクトの変化を直接監視でき、Object.defineProperty () メソッドに依存しなくなりました。これにより、Vue3 はより多くのデータ構造やデータ型をサポートできるようになりました。

  2. より速い初期化とレンダリング速度:Vue3 は内部で参照している Proxy オブジェクトに関連する要素をキャッシュし、優れた初期パフォーマンスを提供し、コンポーネントのアンロード時に関連する最適化を行います。

  3. 無駄な実行の削減:Vue3 は、テンプレートコンパイルの過程でできるだけ多くの情報を注入し、依存関係をマークすることで、無駄な再レンダリングを減らすことができます。

依存追跡メカニズムの最適化#

Vue2 と比較して、Vue3 は依存追跡メカニズムの実装を改善し、無駄な計算を減らし、パフォーマンスを向上させています。具体的な詳細は以下の通りです:

  1. Proxy オブジェクトによる依存追跡の実現:Vue3 は新しい Proxy API を使用して依存追跡メカニズムを実現しています。この方法は、Vue2 の Object.defineProperty () よりも速く、より多くの反射プロパティとキャッチャーを提供します。

  2. コンポーネントレンダリングの render 関数が生成した結果をキャッシュ:Vue3 は render 関数が生成した中間結果をキャッシュし、リアクティブデータが変更されたときのみ再計算します。これにより、不必要な計算や浪費を回避します。

  3. SSR を通じてサーバーサイドレンダリングを最適化:Vue3 は、静的サイト生成(Static Site Generation)という方法を追加し、SSR における初期読み込みデータの遅さの問題を解決します。これにより、フロントエンド開発者はビルド段階で完全にレンダリングされた HTML ファイルを得ることができ、サーバー側の初回データリクエストをほぼ回避でき、初回画面レンダリングの待機時間を効果的に短縮します。

最適化された computed と watch#

computed#

  1. Vue3 では、computed プロパティは固定の getter/setter を使用してリアクティブシステムに登録された関数です。Vue2 とは異なり、Vue3 ではキャッシュ(cache)方式を採用し、計算プロパティの計算結果が使用されたかどうかを記録します。

  2. computed の依存データが変化すると、その computed は 'dirty' 状態にマークされ、スケジューリング関数を通じて更新を待機します。計算プロパティが読み取られたときのみ再計算され、結果がキャッシュされます。これらの重要な変更により、計算プロパティは実装上、以前よりも効率的で予測可能かつ追跡可能になりました。

watch#

  1. Vue3 では、watch は新しいスケジューラー API の恩恵を受けています。スケジューラーは、開発者が自分のニーズに応じて非同期動作の方法とタイミングを細かく制御できるようにします。

  2. カスタムスケジューラーを作成することで、開発者は自動実行コールバックを無効にしたり、次のフレームの前にその実行を一時停止したりできます。また、スケジューラーを通じてコールバックが決して繰り返し実行されないことを保証し、無限キューを防ぐために最大キュー長を設定することもできます。

  3. 概括すると、Vue3 は computed と watch の両方で相応の最適化を行いました。computed に対しては、キャッシュ方式を採用して計算プロパティを最適化し、パフォーマンスが向上しました。watch に対しては、新しいスケジューラー API を使用して非同期動作を制御し、特定のシーンでの使用効率と制御性を向上させました。

 


 

より速いレンダリング性能#

静的ツリーのホイスト(Static tree hoisting)#

静的ツリーのホイスト(Static Tree Hoisting)とは、動的に生成された仮想 DOM ツリーの中で、頻繁に更新する必要のないノードを動的ノードから静的ノードに変換するプロセスを指します。Vue3 では、静的ツリーのホイストはコンパイラによって実現され、主に以下の二つの方法で実行時のパフォーマンスを最適化します:

1. 静的ノードのホイスト

不変の静的ノードに対して、Vue3 は自動的にそれらを静的ノードとしてマークし、毎回の再描画時にこれらのノードを再利用できるようにします。これにより、不必要な再作成や破棄を回避できます。これにより、内部アルゴリズムの複雑さとアプリケーションの CPU 使用率を大幅に低下させることができます。

2. 静的プロパティのホイスト

静的プロパティ(class や style など)を含む動的ノードに対して、Vue3 コンパイラはそれらを自動的に静的プロパティにホイストします。コンポーネントが実行される際に、これらの静的プロパティを再計算する必要がなくなります。

マークとホイスト(Patch flag and Static props hoisting)#

1. マーク (Patch flag)

Vue2 では、データが変化すると仮想 DOM は新旧ノードを比較し、どのノードを更新する必要があるかを判断します。このプロセスは「Diff アルゴリズム」と呼ばれ、二つのツリー構造を比較する際に、ツリー全体を遍歴する必要があり、パフォーマンスに大きな影響を与えます。Vue3 では、新しい仮想 DOM 最適化方案 - Patch flag を提案しています。

Patch flag は、動的バインディング指令の要素やコンポーネントを変化の特徴に基づいてマークし、Virtual DOM が diff 比較を行う際に、Patch Flag を持つ要素やコンポーネントのみを考慮するようにします。これにより、再計算や不必要な DOM 操作の回数を大幅に減らし、レンダリング性能を向上させます。

2. ホイスト(Static props hoisting)

Vue2 では、コンポーネントを再レンダリングするたびに静的プロパティも再作成され、不必要なパフォーマンスの浪費が発生します。Vue3 は「静的プロパティのホイスト」(Static props hoisting)を導入し、レンダラーがコンパイル段階で決して変わらないプロパティを抽出し、レンダリング結果に直接適用できるようにします。これにより、次のコンポーネントをレンダリングする際に、再度それらを計算する必要がなくなります。

二つの方案の実現はすべてコンパイル時に行われるため、レンダリングに必要な時間とパフォーマンスのオーバーヘッドを減少させ、Vue3 により速いレンダリング速度と高い効率を与えます。

イベントハンドラのキャッシュ(Cache handlers)#

イベントハンドラをキャッシュすることで、コンポーネントのパフォーマンスを最適化します。

Vue2 では、各リスニングイベントに対して、再レンダリングのたびに新しいハンドラ関数を作成する必要があり、これが大量の不必要な関数のインスタンス化を引き起こす可能性があります。Vue3 では、イベントキャッシュを通じてこの状況を回避できます。

コンポーネントがアクティブ状態から非アクティブ状態に変わると(例えば、v-if 条件が成立しない場合)、Vue はそのすべてのイベントハンドラを破棄します。コンポーネントが再びアクティブ状態に入ると(条件が true に変わると)、Vue3 は以前にキャッシュされたハンドラ関数を再利用できるため、イベントリスナーの挿入と削除のオーバーヘッドを削減します。

具体的な実装方法は、コンポーネント内部に PatchFlag を維持し、コンポーネントがキャッシュイベントを持っているかどうかを示し、イベントが正しくトリガーされると同時に、キャッシュイベントも更新されることを保証します。

全体的に、イベントキャッシュにより、同じイベントハンドラをコンポーネントが複数回レンダリングされる際に再利用できるようになり、不必要な関数のインスタンス化を大幅に削減し、アプリケーションのパフォーマンスを向上させます。

メモリ管理の最適化#

1. 静的マーク(Static marking)

Vue3 では、静的マーク技術を使用して、テンプレート、指令、スタイルなどの静的コンテンツを事前コンパイルし、アプリケーション起動時に初回レンダリングを行います。この処理方法により、静的コンテンツは再度解析や作成を行う必要がなくなり、メモリ使用量が大幅に削減されます。

2. 静的ホイスト(Static hoisting)

静的ホイストは別の最適化手法で、コンポーネントの静的コンテンツの中から再利用可能な部分を見つけ、HTML テンプレートから抽出します。これにより、コンポーネントのレンダリング性能が最適化され、メモリスペースも節約されます。

3. バッチ更新(Batch updates)

Vue3 の更新メカニズムは、バッチ更新方式を採用して不必要な DOM 操作や計算を減少させます。Vue3 は、すべての待機更新値をキャッシュし、ビューを更新する必要があるときに一括処理を行うことで、重複した計算やレンダリング操作を回避します。

4. ゼロプロキシ(Zero proxy)

Vue3 のリアクティブオブジェクトはゼロプロキシ技術を採用しており、getter または setter が呼び出されたときにのみ、新しいリアクティブオブジェクトを作成したり、関数をラップしたりします。この方法により、オブジェクトが占有するメモリを削減し、コードの実行効率を向上させます。

5. 非同期タスク(Async handling)

Vue3 の非同期レンダリングは、アプリケーションのパフォーマンスを大幅に向上させます。非同期スレッドで時間のかかる操作(コンポーネントのレンダリング、データ変更など)を処理することで、メインスレッドのブロックを減少させ、ユーザー操作時のカクつきを回避し、アプリケーションの応答速度を向上させます。

6. Tree shaking

Vue3 は軽量性を保ち、不要なコードを最終ビルド結果に含めないように、Tree shaking 技術を採用しています。この技術により、JavaScript 内で参照されていない無用なモジュールや関数を削除し、直接参照されるコードのみをバンドルすることで、アプリケーションのサイズを小さくし、実行速度を向上させます。

7. コンパイルキャッシュ(Compilation caching)

Vue3 はコンパイラレベルでコンパイルキャッシュ機能を導入し、すでにコンパイルされたテンプレートをキャッシュします。次回再実行する際には、まずキャッシュ内で対応するコンパイル結果を探し、見つからない場合は再度コンパイルを行います。この機能により、アプリケーションの起動速度が大幅に向上します。

 


 

より良い TypeScript サポート#

型推論と型チェック#

1. 型推論(Type inference)

Vue3 は型推論を通じてコード内の type annotations を減少させることをサポートしています。これにより、開発者はより簡潔で明確なコードを記述でき、すべての変数、関数パラメータ、戻り値に明示的な型宣言を追加する必要がなくなります。

2. 型チェック(Type checking)

Vue3 は TypeScript を使用して構文解析と型チェックを行い、潜在的な型エラーやコーディング問題を早期に発見し、捕捉します。一般的な型チェックシーンには、prop 型チェック、コンポーネントイベント型チェックなどがあります。

型宣言ファイル#

1. 完全な型宣言ファイル

Vue3 は完全な TypeScript 型宣言ファイルを提供し、真の意味で TypeScript アプリケーションを構築でき、コンパイラを使用して開発過程で型安全性を保証します。

2. Vue コンポーネントのサポート

Vue3 の型宣言ファイルは、コンポーネント props、テンプレート指令型などの型定義と検証をサポートし、コンポーネント開発プロセスを大幅に簡素化し、型エラーによる時間のかかるデバッグを回避します。

3. オブジェクトマージのサポート

Vue3 の型宣言ファイルは、オブジェクトマージの方式を通じて型を拡張することもサポートしています。この機能は、依存注入、プラグイン、ミックスイン(mixin)など、コンポーネントオプションを変更する可能性のある非常規のアプリケーションシーンに適用されます。

4. Class Component のサポート

Vue3 の型宣言ファイルは、Vue の Class Component にも対応しています。クラスコンポーネントは、通常のコンポーネントの変種と見なすことができ、コンポーネントオプション API を使用しますが、メソッドやライフサイクルフックは、クラスの静的メソッドやインスタンス関数のように見えます。

 


 

Composition API#

Options API との違い#

主な違いは以下の通りです:

1. データとロジックの再利用

Options API のコンポーネントは、テンプレート、スタイル、JavaScript コードなどの複数の部分で構成されています。コンポーネント内部で定義されたデータやメソッドは、現在のコンポーネント内のテンプレートや JavaScript コードでしか使用できません。

Composition API は、同じロジックブロックを処理するために個別の関数を使用し、これらの関数を組み合わせて再利用を実現できます。このメカニズムにより、類似の機能を複数のコンポーネント間で繰り返し使用でき、Options API で発生する大量の重複コードを回避できます。

2. 型定義のサポート

Options API は TypeScript 型定義をサポートしていますが、型は特定のオプションオブジェクトやライフサイクル関数に制限されます。

Composition API は、TypeScript の能力を利用して関数パラメータや戻り値に対して正確な静的型チェックを行うことを許可します。これにより、アプリケーションでのランタイム型エラーの発生を防ぐことができます。

3. ライフサイクルフック

Options API では、ライフサイクルフック関数が異なるライフサイクル段階に分散しています。そのため、Options API を使用してコードを管理する際、コンポーネントコードが論理的に混乱し、コードが散漫になることがあります。

Composition API は、onMounted、onUpdated、onUnmounted など、より表現力豊かで可読性の高いライフサイクルフック関数を提供し、コンポーネント開発をより良くサポートします。

4. その他の技術的特性

Composition API では、定数をエクスポートすることで再利用可能な状態ロジックを実現し、プラグインベースのカスタムロジックライブラリを構築できます。これは Vue 2.x の Mixins や HOCs に似ていますが、依存注入、ネームスペースなどの特性により、より強力です。

setup 関数の使用#

Vue3 では、setup 関数はコンポーネントのエントリ関数であり、コンポーネントを設定するために使用され、以下の特性があります:

1. props と context にアクセス可能

setup 関数はコンポーネントの props にアクセスでき、第二引数を通じてコンポーネントのコンテキスト(context)を取得できます。例えば、$attrs、$emit、$slots、$refs などです。

2. リアクティブデータ処理

Vue3 では新しい ref、reactive などのリアクティブ API が導入され、setup 関数内で変数をリアクティブデータに変換できます。これらのデータはテンプレート内で直接使用できます。例えば:

<script>
import { ref } from 'vue'

export default {
    setup() {
        const count = ref(0)
        return {
            count
        }
    }
}
</script>

// テンプレート内で count 変数を使用

<template>
    <div>{{ count }}</div>
</template>

3. オブジェクトを返すことを推奨

setup 関数では、オブジェクトを返すことを推奨します。これにより、コンポーネント内部の変数やメソッドをより明確に公開できます。

4. ライフサイクルフック

setup 関数内でライフサイクルフックを使用できます。例えば、onMounted、onUpdated、onUnmounted などの関数です。

5. 計算プロパティと監視プロパティ

setup 関数内で計算プロパティと監視プロパティを宣言できます。計算プロパティは computed 関数を使用して作成し、監視プロパティは watch 関数を使用して作成します。

import { reactive, computed, watch } from 'vue'

export default {
    setup(props) {
        const state = reactive({
            count: 0,
            doubleCount: computed(() => state.count * 2)
        })

        watch(
            () => props.userId,
            (userId) => {
                // userId が変化した場合の処理
            }
        )

        return {
            ...toRefs(state)
        }
    }
}

ref と reactive の使用#

Vue3 では、ref と reactive を使用してリアクティブデータを作成します。主な違いは以下の通りです:

1. ref

ref は非リアクティブデータ型(基本型やオブジェクトなど)をラップするために使用されます。ref を使用すると、.value を通じてデータにアクセスでき、このデータは外部に対してリアクティブに表現されます。

import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0 を出力
count.value++ // データを変更
console.log(count.value) // 1 を出力

2. reactive

reactive は普通のオブジェクトをラップし、リアクティブデータに変換します。reactive を使用すると、その普通のオブジェクトのプロパティ値が変化すると、そのプロパティに依存するコンポーネントが再レンダリングされます。

import { reactive } from 'vue'

const state = reactive({
    name: '山田',
    age: 18
})

console.log(state.name) // "山田" を出力
state.age++ // データを変更
console.log(state.age) // 19 を出力

注意が必要なのは、reactive で作成されたデータは、すべてのプロパティにドット構文でアクセスする必要があります。また、パフォーマンスの観点から、大量のネストされたリアクティブオブジェクトを避ける必要があります。

例えば、リアクティブオブジェクト内にあまりにも多くのネストされたオブジェクトを定義すると、アプリケーション全体のパフォーマンスに影響を与えます。具体的なビジネスシーンに応じて使用する必要があります。

要するに、ref と reactive は Vue3 でリアクティブデータを作成するための API であり、ref は基本型やオブジェクトの直接ラップに適しており、reactive は普通のオブジェクトのラップに適しています。使用時にはパフォーマンス問題を避け、データアクセスと変更にドット構文を適切に使用することが重要です。

カスタムフック関数#

Vue3 では、カスタムフック関数を通じてコンポーネントロジックを再利用できます。これは React hooks に似ています。カスタムフック関数は、本質的にオブジェクトを返す関数であり、そのオブジェクト内に必要なデータやメソッドを定義します。

例えば、カウントロジックをカプセル化する useCount という名前のフック関数を作成できます。まず、フック関数を定義します:

import { reactive, computed } from 'vue'

export default function useCount() {
    const state = reactive({
        count: 0
    })

    const doubleCount = computed(() => state.count * 2)

    const increment = () => {
        state.count++
    }

    return {
        state,
        doubleCount,
        increment
    }
}

次に、コンポーネント内でカスタムフック関数を使用します:

<template>
    <div>
        <p>カウンター:{{ count }} (倍:{{ doubleCount }})</p>
        <button @click="increment">加算</button>
    </div>
</template>

<script>
import { defineComponent } from 'vue'
import useCount from './useCount'

export default defineComponent({
    setup() {
        const { state, doubleCount, increment } = useCount()
        return {
            count: state.count,
            doubleCount,
            increment
        }
    }
})
</script>

これにより、他のコンポーネントで useCount フック関数を再利用でき、カウント関連のコードを繰り返し記述する必要がなくなります。

注意が必要なのは、カスタムフック関数は setup 関数内でのみ使用できることです。なぜなら、setup 内でのみコンポーネントのコンテキストやライフサイクルフック関数にアクセスできるからです。

 


 

より良いアクセシビリティサポート#

ARIA 属性のサポート#

Vue3 は、アクセシビリティサポートを強化しており、その中には ARIA 属性のサポートも含まれています。ARIA(Accessible Rich Internet Applications)は、障害者向けに開発された属性と状態のセットであり、Web アプリケーションのアクセシビリティを改善します。

Vue3 では、v-bind 指令を使用して ARIA 属性を設定できます。例えば:

<button v-bind="{ 'aria-label': 'ダイアログを閉じる', 'aria-disabled': isDisabled }">閉じる</button>

上記のコードでは、二つの ARIA 属性(aria-label と aria-disabled)をバインドしています。aria-label はボタンのテキストの代替項目を指定し、aria-disabled はボタンが無効状態にあるかどうかを示します。

さらに、Vue3 は ARIA 属性を管理するための組み込みのヘルパー関数を提供し、より便利に管理できるようにしています。例えば、v-bind 指令は、複数の ARIA 属性を同じ要素にバインドするための .bind () 短縮構文も提供しています:

<button :aria-label="getCloseLabel()" :aria-disabled="isDisabled">閉じる</button>

上記のコードでは、 短縮構文と を使用して ARIA 属性をバインドし、別の関数 getCloseLabel を使用してボタンのテキストの代替項目を動的に取得しています。

v-bind 指令の他にも、v-on 指令を使用して ARIA 関連のイベントを設定することができます。例えば:

<button v-on="{ keydown: onKeydown }"></button>

上記のコードでは、v-on を使用して KeyDown イベントをバインドし、onKeydown 関数を通じてそのイベントを処理しています。この過程で、ARIA 属性を使用して開いているメニューの回転方向などの操作を示すことができます。

要するに、Vue3 は ARIA 属性に対する完全なサポートを提供し、アクセシビリティの良い Web アプリケーションをより簡単に開発できるようにしています。

キーボードナビゲーションのサポート#

Web アプリケーションにおいて、キーボードナビゲーションは障害者や補助デバイスを使用するユーザーにとって非常に重要です。

Vue3 でキーボードナビゲーションを実現するには、通常以下の三つの側面を組み合わせる必要があります:

  1. tabindex 属性を使用して要素をフォーカス可能としてマークします。例えば、button 要素の tabindex="0" を設定することで、フォーカス可能な要素にすることができます。

  2. キーボードイベントをリッスンしてキーボードナビゲーション操作を処理します。例えば、keydown イベント内で押されたキーの値をリッスンし、そのキーの値に基づいて次のフォーカス要素や前のフォーカス要素にジャンプするなどの操作を実行します。

  3. キーボードイベント処理内で aria-activedescendant 属性を設定し、現在フォーカスされている要素の ID を指定します。これにより、スクリーンリーダーがユーザーに現在フォーカスされている要素の情報を報告するのに役立ちます。

 


 

その他の改善と最適化#

Teleport コンポーネント#

Teleport コンポーネントは、コンポーネントを DOM 構造の他の位置にレンダリングするのを簡単に実現するのに役立ちます。例えば、モーダルコンポーネントがあると仮定します:

<template>
    <div class="modal">
        <h2>{{ title }}</h2>
        <p>{{ content }}</p>
        <button @click="closeModal">閉じる</button>
    </div>
</template>

<script>
export default {
    props: {
        title: String,
        content: String
    },
    methods: {
        closeModal() {
            this.$emit('close')
        }
    }
}
</script>

使用時には、Teleport コンポーネントを通じてモーダルを他の位置にレンダリングできます。例えば、ページのルート要素の下に:

<template>
    <div>
        <button @click="showModal()">モーダルを表示</button>

        <teleport to="body">
            <Modal v-if="isModalVisible" :title="modalTitle" :content="modalContent" @close="hideModal" />
        </teleport>
    </div>
</template>

<script>
import { ref } from 'vue'
import Modal from './Modal.vue'

export default {
    components: { Modal },
    setup() {
        const isModalVisible = ref(false)
        const modalTitle = ref('')
        const modalContent = ref('')

        function showModal() {
            modalTitle.value = 'モーダルタイトル'
            modalContent.value = 'モーダルコンテンツ'
            isModalVisible.value = true
        }

        function hideModal() {
            isModalVisible.value = false
        }

        return { isModalVisible, modalTitle, modalContent, showModal, hideModal }
    }
}
</script>

上記のコードでは、teleport コンポーネントを通じてモーダルをページのルート要素の下にレンダリングし、私たちの要求を実現しています。Teleport の使用法では、to 属性を使用してレンダリングのターゲット位置を指定できます。例えば、ここでは body を指定しています。

要するに、Vue3 の Teleport コンポーネントは、コンポーネントを他の位置に簡単にレンダリングするのを助け、ページ上に動的にコンポーネントを挿入 / 移動する必要があるアプリケーションの開発に非常に便利なツールです。

Suspense コンポーネント#

Suspense コンポーネントは、非同期にコンポーネントを読み込む際に代替コンテンツを表示するのに役立ち、より良いユーザー体験を提供します。例えば、非同期コンポーネントを使用する際に、Suspense コンポーネントを通じて読み込み中のヒントを表示し、ユーザーにデータが読み込まれていることを知らせることができます。

以下の例は、Suspense と非同期コンポーネントを使用する方法を示しています:

<template>
    <div>
        <h1>非同期コンポーネントデモ</h1>

        <Suspense>
            <!-- 非同期コンポーネントを表示 -->
            <template #default>
                <AsyncComponent />
            </template>

            <!-- 代替コンテンツを表示 -->
            <template #fallback>
                <div>読み込み中...</div>
            </template>
        </Suspense>
    </div>
</template>

<script>
import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'))

export default {
    components: {
        AsyncComponent
    }
}
</script>

上記のコードでは、まず defineAsyncComponent 関数で非同期コンポーネントを定義し、テンプレート内で Suspense コンポーネントで包み、#fallback スロットを使用して代替の読み込みヒント情報を提供しています。

非同期コンポーネントが読み込まれると、デフォルトスロットの内容、つまり AsyncComponent がレンダリングされます。非同期コンポーネントがまだ読み込まれていない場合は、Suspense 内の代替コンテンツスロット(ここでは読み込み中... のヒント情報)が表示されます。

注意が必要なのは、Suspense コンポーネントはデフォルトスロットを一つしか持てませんが、代替コンテンツのスロットは複数持つことができます。このデフォルトスロット内には、非同期コンポーネントや他の非同期で読み込む必要がある内容を一つだけ配置できます。

その他の API と構文の改善#

Vue3 には以下の API と構文の改善があります:

  1. createApp 関数:createApp は新たに Vue アプリを作成するための API です。Vue2 で new Vue () を使用するのとは異なり、Vue3 ではまず createApp 関数を通じてアプリインスタンスを作成し、その上にコンポーネントや他の設定をマウントします。

  2. 改善されたテンプレートコンパイラ:Vue3 では、テンプレートコンパイラが再構築され、最適化された新バージョンは、テンプレートをより速くコンパイルし、より小さなコードパッケージを生成します。

  3. プレフィックスが「v-」の指令名は動的バインディングをサポートします:Vue3 では、すべてのプレフィックスが「v-」の指令は、ブラケット表記法を使用してその名前を動的にバインドできます。例えば:

<div :[attribute]="value"></div>
  1. 改善されたリアクティブシステム:Vue3 では、リアクティブ変数の追跡がパフォーマンス効率を向上させ、ネストされたオブジェクト、Map、Set などの複雑なデータ型のリアクティブ更新をサポートしています。

  2. 新しいライフサイクルメソッド:Vue3 では、beforeUnmount と onRenderTracked の二つのライフサイクルメソッドが追加され、開発者が特別な操作を実行し、コードを最適化するのに便利です。

  3. より柔軟なスロット:Vue2 のスコープスロットとは異なり、Vue3 のスロットはより柔軟な書き方を採用しています。v-slot または # を使用してスロットを定義でき、名前付きスロット、スコープスロット、動的スロットなどをサポートします。

  4. カスタムレンダラー API の導入:開発者は、Vue が開放するカスタムレンダラー API を使用して、カスタムレンダラーを作成し、Vue を canvas などの非 DOM ツリー環境にレンダリングできるようになりました。

 


 

Vue 3 の互換性問題#

Vue 2 との互換性問題#

Vue 3 は Vue 2 に比べて、API と構文に多くの重大な改善が行われているため、Vue 2 との互換性がない場合があります。以下は Vue 3 の互換性問題とその解決策です:

1. 非同期コンポーネント:Vue 2 では、非同期コンポーネントを導入する際に import () 内で Promise を使用して遅延読み込みを実現できますが、Vue 3 では新しい defineAsyncComponent メソッドを使用して非同期コンポーネントを定義する必要があります。しかし、setup 関数や Suspense コンポーネントなどの新機能を通じて、コードの柔軟性を高めることができます。

2. フィルター:Vue 2 で一般的なフィルターは廃止され、Vue 3 では計算プロパティや関数などの方法を使用することを推奨しています。

3. ミックスイン:Vue 2 では、開発者はロジックをミックスインとして抽象化し、コンポーネント内のコードを簡素化できます。しかし、Vue 3 ではミックスインが廃止され、Composition API を使用して記述することが推奨されています。

4. listeners 属性の削除:Vue2 では、listeners 属性が存在し、親コンポーネントが子コンポーネントのリスニングイベントを継承できましたが、Vue 3 ではこの属性が削除されました。v-on="$attrs" を使用することを推奨します。

サードパーティライブラリとの互換性問題#

Vue 3 は API と構文に多くの重大な改善が行われているため、Vue 2 のサードパーティライブラリが Vue 3 で正常に動作しないか、適切な変更が必要になる場合があります。以下は影響を受ける可能性のあるサードパーティライブラリとその解決策です:

1. Vuex

Vuex は Vue アプリケーションのための状態管理パターンとライブラリです。Vue 3 では、Vuex が Vue 3 に対応したバージョンをリリースしており、開発者は直接 vuex@next から最新バージョンをインストールできます。

2. Vue Router:

Vue Router は、シングルページアプリケーションで一般的に使用される完全なルーティングソリューションです。Vue 3 では、Vue Router が最新バージョン(4.x)をリリースし、Vue 3 をサポートしています。開発者は直接 [email protected] からこのバージョンをインストールできます。

3. Element UI:

Element UI は Vue.js 2.0 に基づくデスクトップ向けコンポーネントライブラリです。プロジェクトで Element UI を使用している場合、公式が提供する Vue 3 に基づく新バージョン(3.0)にアップグレードする必要があります。また、開発者は公式ドキュメントを参考にして変更を行うことができます。

4. Axios:

Axios は、ブラウザと Node.js 環境で HTTP リクエストを送信するための Promise ベースの HTTP ライブラリです。Vue 3 では、Axios ライブラリは正常に動作し、他の類似のサードパーティライブラリを代わりに使用することもできます。

注意が必要なのは、すべてのサードパーティライブラリがすでに Vue 3 のバージョンにアップグレードされているわけではないことです。特定のサードパーティライブラリに依存しているプロジェクトの場合は、必ずドキュメントを確認するか、そのライブラリの開発者と連絡を取って詳細な情報を得ることをお勧めします。

 


 

まとめと展望#

Vue 3 の利点と欠点#

利点:

1. 学びやすく使いやすい:Angular や React に比べて、Vue 3 の API 設計と構文はよりシンプルで理解しやすく、学習コストと開発の難易度を低下させます。

2. リアクティブで効率的:Vue 3 のリアクティブシステムは、Proxy に基づく実装方式を採用しており、より高いパフォーマンスを持ち、動的にプロパティや配列要素を追加する操作をサポートします。これにより、開発体験が向上します。

3. 組み合わせ可能な API:Vue 3 の組み合わせ可能な API は、より良いコードの整理性、再利用性、テスト性を持ち、Vue コンポーネント内の状態やロジックをより柔軟に作成し、管理できるようにします。

4. 未来志向の特性:Vue 3 は JavaScript 技術スタックにおいてより先進的で、TypeScript の使用や関数型プログラミングのサポート、より充実した Types API などを提供しています。

5. 開箱即用のツールチェーン:Vue 3 は、Vue CLI、Vuex、Vue Router などの完全なツールチェーンを提供し、開発者が必要とするさまざまな機能を満たすことができます。

欠点 :

1. 小規模化:Vue フレームワークは国内外のインターネット企業で広く使用されていますが、Angular や React に比べて市場シェアが小さく、そのためエコシステムやコミュニティも相対的に小さいです。

2. 小規模チームによる開発:Vue.js のコアチームは経験豊富ですが、人数が少なく、フルタイムでメンテナンスを行う人員が不足しています。

3. エコシステムの不十分さ:Vue.js は、Vuex や Vue Router などの豊富な周辺ツールセットを提供していますが、Angular や React の大規模なエコシステムに比べて、Vue の拡張ライブラリは欠如しているか、十分ではない場合があります。

未来の発展方向#

以下は、今後の発展方向として考えられるいくつかのポイントです:

1. より良いパフォーマンス:Vue 3 はパフォーマンス面で大きな改善が見られますが、さらなる改善の余地があります。将来的には、WebAssembly や Workers などの新技術を探求してパフォーマンスを向上させることができるでしょう。

2. より良い組み合わせ可能性:Composition API により、開発者はより簡単に組み合わせ可能なコンポーネントを作成し、コードの再利用を促進できます。将来的には、この API をさらに改善し、機能や柔軟性を増す可能性があります。

3. より良いツールサポート:Vue 3 の普及に伴い、ツールもより柔軟になります。例えば、開発者が Vue 3 をより効率的に使用できるようにするためのより良い開発ツールやプラグインを開発することができます。

4. より良いクロスプラットフォームサポート:Vue 3 は、Web、ネイティブ、デスクトップアプリケーションで使用する能力を持っていますが、将来的には VR や AR などの他のプラットフォームをより良くサポートする可能性があります。

5. より豊富な可視化ライブラリ:Vue 3 のエコシステムは、さまざまなニーズを満たすために、より多くの可視化ライブラリを発展させ、より良いユーザー体験を提供する可能性があります。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。