Vueはミックスインを使用してコンポーネントを最適化します

Vueはミックスインを使用してコンポーネントを最適化します

Vue は mixins API を提供します。これにより、コンポーネントから再利用可能な関数を抽出し、それを mixins に配置し、コンポーネントに mixins を導入することができます。これにより、コンポーネントの肥大化が軽減され、コードの再利用性が向上します。

ミックスインを理解するには?ミックスインは、1 つ以上のミックスインを含む配列と考えることができます。ミックスインの本質は、データ、作成、メソッドなど、Vue インスタンスのすべてのプロパティを持つことができる JS オブジェクトであり、ミックスインの中にミックスインをネストすることもできます。素晴らしいですね!

以下に簡単な例を示します。

<div id="アプリ">
  <h1>{{ メッセージ }}</h1>
</div>
定数myMixin = {
  データ() {
    戻る {
      メッセージ: 'これはミックスインメッセージです'
    }
  },
  作成された() {
    console.log('ミックスインが作成されました')
  }
}

定数vm = 新しいVue({
  el: '#app',
  ミックスイン: [myMixin],

  データ() {
    戻る {
      メッセージ: 'これは Vue インスタンス メッセージです'
    }
  },
  作成された() {
    console.log(このメッセージ)
    // => ルート Vue インスタンス
    console.log('vueインスタンスが作成されました')
    // => myMixin を作成しました
    // => ルート Vue インスタンスを作成しました
  }
})

Vue インスタンスにミックスインをマージすると、created などのフック関数が配列にマージされ、ミックスインのフックが優先的に呼び出されます。データとメソッドオブジェクトのキー値が競合する場合は、コンポーネントが優先されます。

PS: ミックスインの概念がまだよくわからない場合は、Vue の公式ドキュメントにアクセスして、Vue ミックスインの基本的な概念と使用方法を確認してください。

ミックスインの実装

では、ミックスインはどのように実装されるのでしょうか? vue がインスタンス化されると、オプションをマージするために mergeOptions 関数が呼び出されます。この関数は、vue/src/core/util/options.js ファイルで宣言されています。

エクスポート関数mergeOptions(
  親: オブジェクト、
  子: オブジェクト、
  vm?: コンポーネント
): 物体 {
  ...
  // child.extends がある場合は、再帰的に mergeOptions を呼び出して属性を実装します。コピー const extendsFrom = child.extends
  if (extendsFrom) {
    親 = mergeOptions(親、extendsFrom、vm)
  }
  // child.mixinsがある場合は、mergeOptionsを再帰的に呼び出してプロパティをコピーします。if (child.mixins) {
    (i = 0、l = child.mixins.length; i < l; i++) の場合 {
      親 = mergeOptions(親、子.mixins[i]、vm)
    }
  }
  // 属性のコピー結果を保存するには、options の空のオブジェクトを宣言します。const options = {}
  キーを離す
  // 親オブジェクトを走査し、mergeField を呼び出して (key in parent) の属性をコピーします。
    マージフィールド(キー)
  }
  // 親オブジェクトを走査し、mergeField を呼び出して (key in child) の属性をコピーします。
    if (!hasOwn(親、キー)) {
      マージフィールド(キー)
    }
  }
  // 属性コピー実装メソッド function mergeField(key) {
    // 貫通割り当て、デフォルトは defaultStrat
    const strat = strats[キー] || defaultStrat
    オプション[キー] = strat(親[キー], 子[キー], vm, キー)
  }
  返品オプション
}

コードを簡潔にするために、mergeOptions 関数の重要でないコードは削除しました。残りの部分を見てみましょう。

const extendsFrom = 子.extends
if (extendsFrom) {
  親 = mergeOptions(親、extendsFrom、vm)
}

まず、extendsFrom 変数が child.extends を保存することを宣言します。extendsFrom が true の場合は、mergeOptions を再帰的に呼び出してプロパティをコピーし、マージ結果を親変数に保存します。

if (child.mixins) {
  (i = 0、l = child.mixins.length; i < l; i++) の場合 {
    親 = mergeOptions(親、子.mixins[i]、vm)
  }
}

child.mixins が true の場合は、mixins 配列をループし、mergeOptions を再帰的に呼び出してプロパティをコピーし、マージ結果を親変数に保存します。

次は親と子のプロパティの割り当てです。

定数オプション = {}
キーを離す

for (親のキー) {
  マージフィールド(キー)
}

for (キー in 子) {
  if (!hasOwn(親、キー)) {
    マージフィールド(キー)
  }
}

属性のコピーの結果を保存し、また mergeOptions を再帰的に呼び出したときの戻り値として、空のオプション オブジェクトを宣言します。

ここでは、最初に for...in が呼び出されて親がループされ、ループ内で mergeField 関数が継続的に呼び出されます。

次に、 for...in を呼び出して子をループします。ここでは少し違いがあります。 hasOwn を呼び出して、キーが親に存在するかどうかを判断します。存在しない場合は、繰り返しの呼び出しを回避するために mergeField 関数を呼び出します。

では、この mergeField 関数は具体的に何に使用されるのでしょうか?

関数 mergeField(キー) {
  // 貫通割り当て、デフォルトは defaultStrat
  const strat = strats[キー] || defaultStrat
  オプション[キー] = strat(親[キー], 子[キー], vm, キー)
}

mergeField 関数はキーを受け取り、最初に strat 変数を宣言します。strats[key] が true の場合、strats[key] を strat に割り当てます。

const strats = config.optionMergeStrategies
...
オプションマージ戦略: Object.create(null)、
...

strats は実際には Object.create(null) です。Object.create は新しいオブジェクトを作成するために使用されます。デフォルトでは、strats は Object.create(null) を呼び出すことによって生成される空のオブジェクトです。

ちなみに、vue は Vue.config.optionMergeStrategies も公開しており、カスタム オプションのマージ戦略を実装できます。

strats[key] が false の場合、ここで || を使用して貫通代入を実行し、defaultStrat デフォルト関数を strat に代入します。

const defaultStrat = function(親値: 任意、子値: 任意): 任意 {
  childVal === undefined を返します。parentVal : childVal
}

defaultStrat 関数は三項式を返します。childVal が未定義の場合は parentVal を返し、それ以外の場合は childVal を返します。ここでは ChildVal が優先されるため、コンポーネント > ミックスイン > 拡張の優先順位が付けられます。

mergeField関数は最終的にstratを呼び出した結果をoptions[key]に割り当てます。

mergeOptions 関数は最終的にすべてのオプション、ミックスイン、拡張をマージし、オプション オブジェクトを返して、Vue をインスタンス化します。

フック関数のマージ

フック関数がどのようにマージされるかを見てみましょう。

関数mergeHook(
  parentVal: ?Array<関数>,
  childVal: ?Function | ?Array<Function>
): ?配列<関数> {
  childValを返す
    ? 親値
      ? 親Val.concat(子Val)
      : Array.isArray(childVal)
      ? 子値
      : [子値]
    : 親値
}

LIFECYCLE_HOOKS.forEach(フック => {
  strats[フック] = mergeHook
})

LIFECYCLE_HOOKS 配列をループし、mergeHook 関数を継続的に呼び出して、戻り値を strats[hook] に割り当てます。

エクスポートconst LIFECYCLE_HOOKS = [
  '作成前'、
  「作成された」、
  'マウント前'、
  「マウント」、
  'beforeUpdate'、
  「更新済み」、
  'beforeDestroy'、
  「破壊された」、
  「アクティブ化」、
  「無効化」、
  'エラーキャプチャ'
]

LIFECYCLE_HOOKS は、vue のすべてのフック関数の宣言された文字列です。

mergeHook 関数は、3 レベルの深さにネストされた三項式を返します。

childValを返す
  ? 親値
    ? 親Val.concat(子Val)
    : Array.isArray(childVal)
    ? 子値
    : [子値]
  : 親値

最初のレベルでは、childVal が true の場合は 2 番目のレベルの三項式を返し、false の場合は parentVal を返します。

2 番目のレベルでは、parentVal が true の場合は、parentVal と childVal が結合された配列を返し、parentVal が false の場合は、3 番目のレベルの三項式を返します。

3 番目のレイヤーでは、childVal が配列の場合は childVal を返し、そうでない場合は childVal を配列にパッケージ化して返します。

新しいVue({
  作成日: [
    関数() {
      console.log('進め、進め、進め!')
    },
    関数() {
      console.log('アヒル、アヒル、アヒル!')
    }
  ]
})
// => 進め、進め、進め!
// => アヒル、アヒル、アヒル!

プロジェクト実践

もちろん、vue を使用する友人もプロジェクトで element-ui を使用する必要があります。たとえば、テーブルを使用する場合は、テーブルとページネーションに必要な tableData、total、pageSize などのパラメータを宣言する必要があります。

tableMixin に繰り返しデータとメソッドを記述できます。

エクスポートデフォルト{
  データ() {
    戻る {
      合計: 0,
      ページ番号: 1,
      ページサイズ: 10,
      テーブルデータ: [],
      読み込み中: false
    }
  },

  作成された() {
    this.searchData()
  },

  メソッド: {
    //エラーを防ぐために事前に宣言する searchData() {},

    ハンドルサイズ変更(サイズ) {
      this.pageSize = サイズ
      this.searchData()
    },

    現在の変更を処理する(ページ) {
      this.pageNo = ページ
      this.searchData()
    },

    ハンドル検索データ() {
      このページ番号 = 1
      this.searchData()
    }
  }
}

使用する必要がある場合は、直接インポートできます。

'./tableMixin' から tableMixin をインポートします。

エクスポートデフォルト{
  ...
  ミックスイン: [tableMixin],
  メソッド: {
    検索データ() {
      ...
    }
  }
}

コンポーネント内で searchData メソッドを再宣言します。メソッド オブジェクトの形式のキーの場合、キーが同じであれば、コンポーネント内のキーが tableMixin 内のキーを上書きします。

もちろん、axiosMixin を宣言して、mixin 内に mixin をネストすることもできます。

'./tableMixin' から tableMixin をインポートします。

エクスポートデフォルト{
  ミックスイン: [tableMixin],

  メソッド: {
    ハンドルフェッチ(url) {
      const { ページ番号、ページサイズ } = これ
      this.loading = true

      this.axios({
        メソッド: 'post'、
        URL、
        データ: {
          ...this.params、
          ページいいえ、
          ページサイズ
        }
      })
        .then(({ データ = [] }) => {
          this.tableData = データ
          this.loading = false
        })
        .catch(エラー => {
          this.loading = false
        })
    }
  }
}

axiosMixin をインポートします:

'./axiosMixin' から axiosMixin をインポートします。

エクスポートデフォルト{
  ...
  ミックスイン: [axiosMixin],
  作成された() {
    this.handleFetch('/user/12345')
  }
}

axios では、axios の成功とエラーの後続の呼び出しを前処理できるため、多くのコードを節約できます。

伸ばす

ちなみに、extend は mixin に似ています。1 つのオプション オブジェクトのみを渡すことができます。また、mixin の方が優先度が高く、extend 内の同じ名前のキー値を上書きします。

// child.extends がある場合は、再帰的に mergeOptions を呼び出して属性を実装します。コピー const extendsFrom = child.extends
if (extendsFrom) {
  親 = mergeOptions(親、extendsFrom、vm)
}
// child.mixinsがある場合は、mergeOptionsを再帰的に呼び出してプロパティをコピーします。if (child.mixins) {
  (i = 0、l = child.mixins.length; i < l; i++) の場合 {
    親 = mergeOptions(親、子.mixins[i]、vm)
  }
}
// child.extends がある場合は、再帰的に mergeOptions を呼び出して属性を実装します。コピー const extendsFrom = child.extends
if (extendsFrom) {
  親 = mergeOptions(親、extendsFrom、vm)
}
// child.mixinsがある場合は、mergeOptionsを再帰的に呼び出してプロパティをコピーします。if (child.mixins) {
  (i = 0、l = child.mixins.length; i < l; i++) の場合 {
    親 = mergeOptions(親、子.mixins[i]、vm)
  }
}

mergeOptions 関数では、まず extends のプロパティがコピーされ、次に mixin がコピーされます。mergeField 関数が呼び出されると、最初に child キーが取得されます。

extends の同名キーは mixin によって上書きされますが、extends が優先されます。

要約する

Vue でのミックスインの優先順位は、コンポーネント > ミックスイン > 拡張です。

ここでは、一時的に mixin をコンポーネント モジュール化と呼びます。コンポーネント モジュール化を柔軟に使用すると、コンポーネント内の重複コードを抽出し、コードの再利用を実現し、コードをより明確にして、効率を大幅に向上させることができます。

もちろん、ミックスインには探索を待っている魔法のような操作が他にもたくさんあります。

上記は、Vue が mixin を使用してコンポーネントを最適化する方法の詳細です。Vue が mixin を使用してコンポーネントを最適化する方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueでミックスインを使用する方法
  • Vue で Mixin とプラグインを使用する方法
  • Vue Mixinsの使い方
  • Vueはコンポーネントの再利用可能な機能を配布するためにミックスインを使用します
  • Vue における mixin と extend の違いと使用シナリオの詳細な分析
  • Vue ミックスインの使い方の詳しい説明

<<:  Samba を使用して Linux サーバー上で共有ファイル サービスを構築する方法

>>:  Linux環境でIPV6接続をサポートするようにmysql5.6を設定する方法

推薦する

MySQL 8の新機能である降順インデックスの基礎となる実装の詳細な説明

降順インデックスとは何ですか?インデックスについてはよくご存知かもしれませんが、降順インデックスにつ...

Alibaba Cloud Serverにプログラムをデプロイし、ドメイン名を使用して直接アクセスする方法の詳細な説明

何もすることがなかったので、学習用に最も安いAlibaba Cloudサーバーを購入しました。年間3...

画像をMySQLデータベースに保存し、フロントエンドページに表示するための実装コード

目次1. まず、pycharmを使用してDjangoプロジェクトを作成し、関連する環境を設定します。...

Docker クリーニングの一般的な方法と問題点

大規模な開発に Docker を使用する場合でも、クリーンアップ戦略がなければ、ディスクがすぐにいっ...

3つのDocker Nginxログの処理の詳細な説明

社内の同僚は Nginx ログの標準出力、つまりコンソール経由の処理を必要としているため、まずログを...

Linux で MySQL のルート パスワードを変更する方法

序文このサービスは数か月前からMySQLに導入されています。私の仕事は基本的にターミナルで行われるた...

テーブルを作成するための HTML dl、dt、dd タグとテーブル作成テーブル

ウェブサイトの開発とメンテナンスのコストが削減されるだけでなく、コードもよりセマンティックになります...

Vue プロジェクトがページング効果を実現

ページング効果は、参考までにvueプロジェクトに実装されています。具体的な内容は次のとおりです。 1...

MySQL無料インストール版のパスワードの設定と変更に関するチュートリアル

ステップ 1: 環境変数を構成する (解凍パス: G:\mysql\mysql-5.7.21-win...

Vue コンポーネント化の一般的な方法: コンポーネント値の転送と通信

関連する知識ポイント親コンポーネントから子コンポーネントに値を渡す子コンポーネントから親コンポーネン...

Mac で Docker を使用して Oracle をデプロイする方法

Mac で Docker を使用して Oracle をデプロイする方法まずdockerをインストール...

この記事ではSQL CASE WHENの使い方を詳しく説明します

目次シンプルな CASEWHEN 関数:これは、CASEWHEN 条件式関数を使用するのと同じです。...

Vue2.x における双方向バインディングの原理と実装

目次1. 実施プロセス2. オブザーバーを表示する3. ウォッチャーを実装する4. コンパイルを実装...

Linux での MySQL 5.6.24 (バ​​イナリ) 自動インストール スクリプト

この記事では、Linux環境でのmysql5.6.24自動インストールスクリプトコードを参考までに共...

HTTPSの最も優れた説明

皆さんおはようございます。しばらく記事を更新していませんでした。実は、私は流行中に1か月以上家にいて...