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を設定する方法

推薦する

親要素に対する CSS 子要素の配置の実装

解決親要素に position:relative を追加します。子要素に position:abso...

VMware ワークステーションの仮想マシンの互換性の問題に対する解決策

VMware ワークステーションの仮想マシンの互換性の問題を解決するにはどうすればよいですか?ノート...

MySQL初心者はグループ化や集計クエリの煩わしさから解放されます

目次1. グループクエリの概略図2. groupbyキーワード構文の詳細な説明3. 簡単なグループク...

MySQL の結合インデックスと左端一致原則の詳細な説明

序文これまでインターネットでMySQLジョイントインデックスの最左接頭辞マッチングに関する記事をたく...

MySQLでANDとORを組み合わせる問題を解決する

以下のように表示されます。 SELECT prod_name,prod_price FROM pro...

Nginx で Http、Https、WS、WSS を設定する方法

前面に書かれた今日のインターネット分野では、Nginx は最も広く使用されているプロキシ サーバーの...

VMware Workstation Pro が Windows で実行されない場合の解決策

国慶節の休暇後、Windows アップデート後に VMware 仮想マシンが開けなくなり、「VMwa...

CSS でフッターの「下部吸収」効果を実現

よく遭遇する問題: 下部の要素を「下部に貼り付ける」効果を CSS でどのように実現するか。この記事...

Vueタブとキャッシュページを切り替えるいくつかの方法

目次1. 切り替え方法2. タブを動的に生成する3. キャッシュコンポーネント3.1 キープアライブ...

MySQLのロック機構に関する最も包括的な説明

目次序文グローバルロック完全なデータベース論理バックアップFTWRL と set global re...

Docker イメージ管理の一般的な操作コード例

ミラーリングも Docker のコアコンポーネントの 1 つです。ミラーリングはコンテナ操作の基盤で...

Dockerがコンテナを起動するたびに、IPとホストが指定した操作が実行されます。

序文Dockerを使ってHadoopクラスタを起動するたびに、ネットワークカードの再バインド、IPの...

CSSを使用してダークモードとブライトモードを切り替える

Web Skills第5号では、CSSでダークモードやハイライトモードを実装するための技術的なソリュ...

TeamCenter12 にログインする際の 404/503 問題の解決方法

TeamCenter12はアカウントのパスワードを入力し、ログインをクリックすると、404または50...

HTML のセルパディングとセルスペース属性を図で説明します

セル - 表の内容 セルの余白 (表の余白) (cellpadding) - セルの外側の距離を表し...