Vueプロジェクトでよく使われる実践的なスキルのまとめ

Vueプロジェクトでよく使われる実践的なスキルのまとめ

序文

Vue プロジェクト開発では、コードの重複や複雑さなどの問題が起こりやすいです。実際、Vue プロジェクト開発で使用できるテクニックは数多くあります。この記事では、美しいコードを書くのに役立つシンプルで使いやすいテクニックをいくつか紹介します。使用されるテクノロジー スタックは、Vue2.0 + TypeScript + vue-property-decorator + ElementUI です。以下のテクニックが使用されます。

  • マルチレベルのデータとイベントの配信には $attrs と $listeners を使用します
  • データのメンテナンスを容易にするためにデータの双方向バインディングを実現する
  • ミックスインの使用
  • 動的コンポーネントを使用してコンポーネントを遅延ロードする
  • コンポーネントスコープの CSS で ::v-deep を使用してコンポーネントのスタイルを変更します。
  • デコレータを使用したコードの最適化
  • require.context を使用してプロジェクトディレクトリ情報を取得します

1. マルチレベルのデータとイベントの配信には$attrsと$listenersを使用する

まず、静的 Props と動的 Props に分けられる Props を渡す方法について説明します。

<!-- 静的プロパティ -->
<blog-post title="Vue との旅"></blog-post>
<!-- 動的プロパティ -->
<ブログ投稿 v-bind:title="post.title"></ブログ投稿>
<!-- 動的プロップ転送は次のように短縮できます -->
<ブログ投稿:title="post.title"></ブログ投稿>
<!-- 複数のプロパティを渡す必要がある場合は、v-bind でまとめて記述できます -->
<blog-post v-bind="{ 編集可能、タイトル: post.title}"></blog-post>

Props がどのように渡されるかがわかったので、公式ドキュメントで $attrs がどのように定義されているかを見てみましょう。You Dada のドキュメントでは、$attrs は次のように紹介されています。

$attrs: 親スコープ内の、props として認識 (および取得) されない属性バインディングが含まれます (クラスとスタイルを除く)。コンポーネントがプロパティを宣言していない場合、すべての親スコープバインディング(クラスとスタイルを除く)がここに含まれ、v-bind="$attrs"を介して内部コンポーネントに渡すことができます。

$attrs には、親スコープに渡される props で宣言されていない他の props が含まれているため、$attrs を使用して、親コンポーネントでは必要ではないが子コンポーネントに必要な props を置き換え、v-bind="$attrs" を通じてそれらを子孫に均一に渡すことができます。これにより、1 つずつ宣言してから 1 つずつ渡す必要がなくなります。

<ブログ投稿 v-bind="$attrs"></ブログ投稿>

上記のコード行は、このスコープ内の props ではない他の属性を、v-bind="$attrs" を介してブログ投稿コンポーネントに渡します。

親コンポーネントが $attrs を介して子孫コンポーネントに渡された後、子孫コンポーネントはイベントをトリガーして親コンポーネントの状態を更新する場合、何をする必要がありますか?一度に 1 レベルずつイベントを発行すると、コードが煩雑で複雑になりすぎてしまうでしょうか? Vue では、この問題は $listeners によって解決できます。まず、$listeners に関する公式ドキュメントをご覧ください。

親スコープからの v-on イベント リスナーが含まれます (.native 修飾子なし)。これは、v-on="$listeners" を介して内部コンポーネントに渡すことができます。これは、より高レベルのコンポーネントを作成するときに非常に便利です。

ドキュメントには、$listeners には親スコープのイベント リスナーが含まれていると記載されています。つまり、$listeners は親コンポーネントに設定されたイベント リスナーを表します。イベントが自身のコンポーネントではなく親コンポーネントをトリガーする限り、v-on="$listeners" で表すことができます。

<!-- 親コンポーネント (第 1 レベルのコンポーネント) -->
<componentA @on-change="handleChange" v-bind="{ editable, title: post.title}" />

<!-- 中間層コンポーネント -->
<子 v-bind="$attrs" v-on="$listeners"/>

<!-- データ転送のターゲットコンポーネント、イベントによってトリガーされるコンポーネント -->
<div @click="handleClick">{{ title }} </div>
<スクリプト>
  エクスポートデフォルト{
    小道具: {
      タイトル: 文字列
    }
    ハンドルクリック() {
      this.$emit('on-change', '新しいタイトル');
    }
  }
</スクリプト>

上記のコード例では、残りの Props は中間層コンポーネントの v-bind="$attrs" を介して子コンポーネントに渡され、次に親スコープのイベント リスナーが v-on="$listeners" を介してバインドされます。発行されると、親コンポーネントに渡されます。

2. データのメンテナンスを容易にするためにデータの双方向バインディングを実現する

親コンポーネントが子コンポーネントにデータを渡す必要があり、子コンポーネントがデータ更新をトリガーすると、すぐに親コンポーネントにフィードバックされ、親コンポーネントのデータが更新され、一方向のデータが子コンポーネントに流れ、最終的に子コンポーネントが更新される、といったシナリオは数多くあります。通常、ステータスの更新には props + $emit が使用されますが、このアプローチは少し扱いに​​くく、保守も難しいため、データの「双方向バインディング」を実装することでコードの保守性を向上させることができます。これは次の方法で実現できます。

.syncを使用してPropの「双方向バインディング」を実装する

v-bindプロパティに.sync修飾子を追加し、新しい値を割り当てるときにthis.$emit('update:propName', newValue)を使用します。

<!-- .sync は v-on:update モードの略語です -->
<子 v-on:update:title="title" />
<!-- 以下と同等 -->
<子:title.sync="title" />

上記のコードでタイトルの値を更新する場合は、this.$emit('update:title', 'new title') を使用するだけでデータの更新が完了します。

モデルオプションの使用

model は 2.2.0 以降で追加された新しいオプションです。デフォルトでは、コンポーネントの v-model は value という名前の Prop と input という名前のイベントを使用します。model オプションでは、v-model を実装するために Prop 名とイベント名を指定できます。利点は、v-model を実装する際に、Prop 名とイベント名の競合も回避できることです。

<!-- 親コンポーネント -->
<モデル v-model="チェック済み"/>

<!-- モデル コンポーネント -->
<div @click="ハンドルクリック">
  <p>カスタム コンポーネントの v-model</p>
  チェック済み {{checked}}
</div>
<script lang="ts">
エクスポートデフォルト{
  モデル: {
    プロパティ: 'チェック済み'、
    イベント: '変更'
  },
  小道具: {
    チェック済み: ブール値
  },
  メソッド: {
    ハンドルクリック() {
      this.$emit('change', !this.checked);
    }
  }

上記のコードでは、v-model を実装するために、モデル オプションに prop と event を追加するだけです。 Vue + TS プロジェクトでは、vue-property-decorator が Model デコレータを提供します。これは次のように記述する必要があります。

@Model('change', { type: Boolean }) 読み取り専用チェック済み!: boolean
ハンドルクリック() {
  this.$emit('change', !this.checked);
}

.sync とモデルを通じてのみ、データの「双方向バインディング」を実現できます。このようにコードを記述すると、コードをある程度削減でき、コードをよりエレガントで保守しやすいものにすることができます。

3. ミックスインの使用

ミックスインは次の 2 つのシナリオで使用できます。

  1. コンポーネント内の共通コードを抽出してコードの再利用性を高めるために使用します。グローバルに再利用しないでください。コンポーネントまたはページ内で使用するのが最適です。
  2. 機能ポイントを分離するために使用すると、業務機能が多くなり、Vue ファイルの行数が多くなり、コードの保守が困難になり、機能ポイントのコードを追跡するのが難しくなるという状況に遭遇することがあります。この巨大な Vue ファイルは、機能コードを抽出することでより適切に保守できます。

まず、パブリック ミックスイン ファイルを作成し、そこに再利用可能な状態と関数を書き込みます。

デフォルトクラスCommonMixinsをエクスポートし、Vueを拡張します{
    公開ページネーション = {
        ページサイズ: 20,
        合計: 0,
        現在のページ: 1,
    }
    handleChangePageSize (pageSize: 数値、cb: 関数) {
        this.paginations.pageSize = ページサイズ;
        関数 :
    }
    handleChangePageNum (currentPage: 数値、cb: 関数) {
        this.paginations.currentPage = 現在のページ;
        関数 :
    }
}

vue-property-decorator は、Mixin 用のデコレータを提供します。ビジネス ページに Mixin を導入するには、Mixin を渡すだけです。複数の Mixin を渡すことができ、複数の Mixin をミックスインできます。

<script lang="ts">
'vue-property-decorator' から { Component, Mixins } をインポートします。
「./common-mixin」からCommonMixinsをインポートします。
「./permission-mixin」から PermissionMixins をインポートします。
@成分({})
デフォルトクラス Parent をエクスポートし、Mixins(CommonMixins, PermissionMixins) を拡張します。
}
</スクリプト>

1つだけ必要な場合は、直接継承することもできます

<script lang="ts">
'vue-property-decorator' から { Component, Mixins } をインポートします。
「./common-mixin」からCommonMixinsをインポートします。
@成分({})
デフォルトクラスをエクスポートし、親クラスをCommonMixinsに拡張します。
}
</スクリプト>

多くの機能と大量のコードを含むページに遭遇した場合、Mixin を使用して一部の機能を抽出し、これらの機能をファイルを通じて管理することで、コードの管理が容易になります。

4. 動的コンポーネントを使用してコンポーネントを遅延ロードする

コンポーネントは同期的にロードされますが、ページに大量のコンテンツがある場合、ポップアップ コンポーネントなど、一部のコンポーネントは最初にロードする必要はありません。これらは動的コンポーネントを使用して、ユーザーが特定の操作を実行した後にロードできます。これにより、メイン モジュールのロードのパフォーマンスが向上します。Vue では、コンポーネントの動的コンポーネントを使用して、is の値に基づいてレンダリングするコンポーネントを決定できます。

<テンプレート>
  <div>
    ホームページ<br/>
    <button @click="handleClick1">レコード コンポーネント 1 をクリック</button><br/>
    <button @click="handleClick2">レコード コンポーネント 2 をクリック</button><br/>
    <コンポーネント:is="child1"></コンポーネント>
    <コンポーネント:is="child2"></コンポーネント>
  </div>
</テンプレート>
<script lang="ts">
'vue-property-decorator' から Component、Vue } をインポートします。
@成分({})
デフォルトのクラスAsyncComponentをエクスポートし、Vueを拡張します。
  パブリックchild1:Component = null;
  パブリックchild2:Component = null;
  ハンドルクリック1() {
    this.child1 = require('./child1').default;
  }
  ハンドルクリック2() {
    this.child2 = require('./child2').default;
  }
}
</スクリプト>

サンプルコードでは、コンポーネントはクリックされたときにのみ読み込まれます。コンポーネントは v-show を使用して表示および非表示にすることもできるため、パフォーマンスを最適化するためにコンポーネントは 1 回だけマウントされます。

5. コンポーネントスコープのCSSで::v-deepを使用してコンポーネントのスタイルを変更する

UI コンポーネントのスタイルを変更したいが、他の人の使用に影響を与えることを恐れ、スコープを追加しても変更が有効にならないというシナリオは数多くあります。::v-deep ディープセレクターを使用すると、コンポーネントスコープ内で CSS スタイルを変更できます。 CSS では >>> 演算子を使用できますが、プリプロセッサでは /deep/ または ::v-deep を使用する必要があります。

<スタイルスコープ>
>>> .ivu-tabs-tabpane {
        背景: #f1f1f1;
    }
</スタイル>
<style lang="scss" スコープ>
/deep/ .ivu-tabs-tabpane {
        背景: #f1f1f1;
    }
</スタイル>
<style lang="scss" スコープ>
::v-deep .ivu-tabs-tabpane {
        背景: #f1f1f1;
    }
</スタイル>

::v-deep と /deep/ は同じ機能ですが、 /deep/ は推奨されません。Vue 3.0 では、 /deep/ はサポートされません。

6. デコレータを使用してコードを最適化する

デコレータは、コードの読みやすさを向上させ、意図を明確に表現し、クラス内のメソッドにアンチシェイク機能を提供するなど、クラスの機能を拡張または変更するための便利な手段を提供します。

'lodash.debounce' から debounce をインポートします。
エクスポート関数 Debounce(delay: number, config: object = {}) {
  戻り値 (ターゲット: 任意、プロパティ: 文字列) => {
    戻る {
      値: debounce(target[prop], delay, config),
    };
  };
}

これの利点は、非常に使いやすく、コードの読みやすさが向上することです。

@デバウンス(300)
onIdChange(値: 文字列) {
  this.$emit('idchange', val);
}

7. require.contextを使用してプロジェクトディレクトリ情報を取得する

require.context に関しては、webpack のドキュメントでは次のように説明されています。

この関数には、検索するディレクトリ、そのサブディレクトリも検索するかどうかを示すフラグ、およびファイルを一致させる正規表現の 3 つの引数を渡すことができます。
webpack はビルド中にコード内の require.context() を解析します。この機能は、フォルダー内のすべてのファイルをインポートする場合、または正規表現に一致するすべてのファイルをインポートする場合に役立ちます。

このプロンプトに従って、フォルダーの下にあるすべてのファイルを参照し、取得したファイル情報を使用していくつかの操作を実行できます。たとえば、コンポーネントを登録する場合、以前はコンポーネントを 1 つずつインポートして登録する必要があり、後で新しいコンポーネントを追加する場合は、再度記述する必要があります。現在では、 require.context を使用して、このセクションのコードを最適化できます。

// './wms-table/table/index' から WmsTable をインポートします。
'./table/index.vue' からテーブルをインポートします。
'./custom-hooks/custom-hooks-actions/index' から CustomHooks をインポートします。
'./s-filter/filter-form' から SFilter をインポートします。
'./button/index' から WButton をインポートします。
'./createForm/create-form/CreateForm.vue' から CreateForm をインポートします。
'./table/action-table-column.vue' からアクションをインポートします。
'./detail-item.vue' から DetailItem をインポートします。


Vue.component('w-filter', SFilter);
Vue.component('w-button', WButton);
Vue.component('custom-hooks', CustomHooks);
Vue.component('create-form', CreateForm);
Vue.component('w-table', テーブル);
Vue.component('w-table-action', アクション);
Vue.component('zonetime-date-picker', ZonetimeDatePicker);
Vue.component('detail', DetailItem);

グローバル コンポーネントを登録する場合、1 つずつインポートして登録する必要はありません。 require.context を使用してモジュールを自動的にインポートします。これの利点は、新しいコンポーネントを作成するときに手動で登録する必要がなく、最初に自動的に完了することです。

const コンテキスト = require.context('./', true, /\.(vue|ts)$/);
エクスポートデフォルト{
  インストール (vm) {
    contexts.keys().forEach(コンポーネント => {
      定数componentEntity = contexts(component).default;
      if (コンポーネントエンティティ名) {
        vm.component(componentEntity.name、componentEntity);
      }
    });
  }
};

要約する

この記事では、Vue の実践でよく使用されるいくつかのテクニックを紹介します。これらのテクニックの目的は、双方向データバインディングやレベル間のデータ転送を簡単に実装するなど、開発効率を向上させることです。また、非常に実用的なデコレータや、Mixin を使用してコードを分割して機能ポイントを管理するなど、コードの保守性と可読性を向上させることもできます。

Vue プロジェクトでよく使われる実践的なスキルのまとめはこれで終わりです。Vue プロジェクトでよく使われるスキルに関するその他のコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

参考文献

  • コンテキストが必要
  • Vue公式ドキュメント
以下もご興味があるかもしれません:
  • Vueプロジェクトでlessを使用するためのヒント
  • 22 Vue 最適化のヒント (プロジェクトの実践)
  • Vue.js パフォーマンス最適化 N 個のヒント (収集する価値あり)
  • Vue Router の 10 の高度なヒントのまとめ
  • 読めばわかるVueの8つのヒント
  • Vue 要素と Nuxt の使用に関するヒントを共有する
  • Vue 開発における一般的なルーチンとテクニックの概要
  • Vue関数コンポーネントの使用に関する簡単な説明
  • Vue.js でより良い v-for ループを書くための 6 つのヒント
  • 知っておくべき 25 の Vue のヒント

<<:  SQL 文で OR と AND を混在させる場合のヒント

>>:  自動開始および停止コマンドを適用するには、Docker サービスを再起動します (推奨)

推薦する

Vueのキーボードイベントの詳細な説明

目次共通キーエイリアスエイリアスが指定されていないキーシステム修飾キーカスタムキーエイリアス要約する...

Centos7 システムでの MySQL マスター スレーブ同期構成スキーム

序文最近、高可用性プロジェクトに取り組む際には、データの同期が必要になっています。ノードが 2 つし...

MySQL で制限を使用するとパフォーマンスに影響するのはなぜですか?

まず、MySQL のバージョンについて説明します。 mysql> バージョンを選択します();...

MySQLデータベースは重複データを削除し、メソッドインスタンスを1つだけ保持します

1. 問題の紹介ユーザー テーブルに 3 つのフィールドが含まれているシナリオを想定します。 id、...

Adobe Brackets の簡単な使い方のグラフィックチュートリアル

Adobe Brackets は、HTML、CSS、JavaScript 用のオープンソースでシンプ...

Navicat for MySQL 15 登録とアクティベーションの詳細なチュートリアル

1. Navicat for MySQL 15をダウンロードするhttps://www.navica...

ウェブページでグレーまたはブラックモードを実現するための CSS3 フィルターコード

フロントエンドcss3 フィルターは、Web ページのグレー効果を実現できるだけでなく、ナイト モー...

MySQL マルチテーブル結合クエリの詳細な説明

目次複数テーブル結合クエリ内部結合左結合右結合サブクエリ要約する複数テーブル結合クエリテーブル間の接...

ウェブサイトを構築するときは、UTF-8 または GB2312 エンコードを使用する必要がありますか?

外国のウェブサイトを開くと文字化けした文字が表示されることが多く、また、英語以外の外国のウェブサイト...

kindとDockerを使用してローカルKubernetes環境を起動する

導入Kubernetes を使い始めるのに丸一日を費やしたことはありませんか?最近登場したいくつかの...

Linux カーネルの copy_{to, from}_user() に関する考察

目次1. copy_{to,from}_user() とは何か1. copy_{to,from}_u...

Sublime TextがUbuntuで中国語を入力できない問題の最も簡単な解決策

崇高なSublime Text はコード エディター (Sublime Text2 は有料ソフトウェ...

Linuxディレクトリ構造の詳細な紹介

Linuxを学び始めるときは、まずLinuxの標準ディレクトリ構造を理解する必要があります。 / r...

XHTML CSS ページをプリンタ ページに変換する

<br />これまで、Web ページのプリンタ対応バージョンを作成するには、印刷したとき...

MySQLでのカスタムパラメータの使用に関する詳細な説明

MySQL 変数には、システム変数とシステム変数が含まれます。今回の学習課題はユーザー定義変数です。...