Vueカスタム命令とその使用方法の詳細な説明

Vueカスタム命令とその使用方法の詳細な説明

1. 指令とは何ですか?

Vue を学習していると必ず命令文に触れることになりますが、命令文とは何でしょうか?

Vue は、ページとデータに対してより便利な出力を提供します。これらの操作は命令と呼ばれ、HTML ページの属性 <div v-xxx ></div> など、v-xxx で表されます。

たとえば、Angular では、ng-xxx で始まるコマンドはディレクティブと呼ばれます。

命令はいくつかの DOM 動作をカプセル化し、属性と組み合わせてコードとして保存します。コードには対応する値があり、異なる値に応じて関連する DOM 操作がバインドされます。つまり、いくつかのテンプレート操作を実行できます。

Vue でよく使われる組み込みの v ディレクティブ

  • v-text: 要素の innerText プロパティ。二重タグでのみ使用可能。{{}} と同じ効果があり、めったに使用されない。
  • v-html: 要素の innerHTML。要素の innerHTML に実際に値を割り当てます。
  • v-show: CSS スタイルに基づいて要素の表示と非表示を切り替えます。非表示にする場合は、要素のスタイルに display: none を追加します。
  • v-if: 要素の挿入と削除の操作は、要素の破棄と作成と同等です。式の値が false の場合、マーカーとして<!---->が残されます。将来的に v-if の値が true になった場合は、ここに要素が挿入されます (else がある場合は、別のピットを残しません)。
  • v-else-if: 前の隣接要素にはv-ifまたはv-else-ifが必要です
  • v-else: 前の隣接要素には v-if または v-else-if が必要です。v-if と v-else-if の両方に対応する式がある場合は、v-else を直接記述できます。
  • v-for: データ セット (配列またはオブジェクト) をループしてレンダリングするために使用されます。特定の構文を使用する必要があります: v-for="alias in expression"。注意: v-for と v-if が同じノードにある場合、v-for は v-if よりも優先されます。つまり、v-ifは各v-forループで実行される。
  • v-on: 主に dom イベントを監視し、いくつかの操作を実行するために使用されます。 [@]と省略
  • v-model: input/textarea などのフォーム コントロールで双方向データ バインディングを作成するために使用されます。
  • v-bind: 1 つ以上の属性を動的にバインドします。通常は、クラス、スタイル、href などをバインドするために使用されます。
  • v-once: コンポーネントと要素は 1 回だけレンダリングされ、データが変更されても再レンダリングされません。

v-if と v-show の比較

  • v-if は、条件ブロック内のイベント リスナーと子コンポーネントが切り替え中に適切に破棄され、再作成されることを保証するため、真に条件付きのレンダリングです。
  • v-if も遅延処理です。最初のレンダリング時に条件が false の場合、条件が最初に true になるまで何も実行されず、その後条件ブロックがレンダリングされます。
  • 対照的に、v-show ははるかにシンプルです。初期条件が何であっても、要素は常にレンダリングされ、CSS に基づいて単純に切り替えられます。

一般的に、v-if は切り替えコストが高く、v-show は初期レンダリング コストが高くなります。したがって、非常に頻繁な切り替えが必要な場合は v-show を使用する方が適切であり、実行時に条件がほとんど変化しない場合は v-if を使用する方が適切です。

実際の開発プロセスでは、これらの組み込み命令がすべてのニーズを満たさない可能性があり、要素にいくつかの特別な機能を追加する必要がある場合もあります。このとき、Vue が提供する強力かつ柔軟な機能「カスタム命令」を使用する必要があります。

公式 API ドキュメントには次のような一文があります: カスタム命令は、通常の DOM 要素に対して低レベルの操作を実行するために使用されます。つまり、カスタム命令が解決する問題、または使用シナリオは、通常の DOM 要素に対して低レベルの操作を実行することであるため、カスタム命令を盲目的に使用することはできません。

2. カスタム命令のフック機能

Vue はカスタム命令用に 5 つのフック関数を提供します。

  • bind: ディレクティブが最初に要素にバインドされたときに呼び出され、1 回だけ実行されます。ここで、1 回限りの初期化セットアップを実行できます。
  • 挿入: バインドされた要素は、親ノードの DOM に挿入されたときに呼び出されます (親ノードのみが存在することが保証されます)。
  • update: コンポーネントが更新されたときに呼び出されます。
  • componentUpdated: コンポーネントとサブコンポーネントが更新されたときに呼び出されます。
  • unbind: 命令が要素からアンバインドされ、1 回だけ実行されるときに呼び出されます。

知らせ:

1.updateおよびcomponentUpdatedフック関数を除き、各フック関数にはel、binding、vnodeの3つのパラメータが含まれます。

2. 各関数の最初のパラメータは常に el であり、これは命令がバインドされている DOM 要素を表します。この el パラメータはネイティブ JS オブジェクトであるため、Vue カスタム命令を使用して DOM と直接対話できます。

3.bindingは、name、value、oldValue、expression、arg、modifiersの属性を含むオブジェクトです。

4.oldVnodeはupdateとcomponentUpdatedフックでのみ有効です

5. elを除き、binding属性とvnode属性は読み取り専用です。

簡単に言うと、フック関数はライフサイクルです。つまり、ディレクティブが要素にバインドされると、ディレクティブ内に 5 つのライフサイクル イベント関数が存在します。次に、これらのフック関数のトリガーを確認するためのケースを作成します。

<p v-test>これはテキストの段落です</p>
​
エクスポートデフォルト{
    ……
    ディレクティブ: {
        テスト: {
              バインド(){
                コンソールログ('バインド')
              },
              挿入された(){
                console.log('挿入されました')
              },
              アップデート () {
                コンソールログ('更新')
              },
              コンポーネントが更新されました () {
                console.log('コンポーネントが更新されました')
              },
              アンバインド(){
                console.log('アンバインド')
              }
        }
    }
}

結果:

ページがレンダリングされると、bind 関数と insert 関数がトリガーされます。では、他の 3 つのフック関数はいつトリガーされるのでしょうか?

アップデートに関する公式説明:

update: コンポーネントの VNode が更新されたときに呼び出されますが、子 VNode が更新される前に発生することもあります。命令の値は変更されている場合と変更されていない場合があります。ただし、更新前と更新後の値を比較することで、不要なテンプレートの更新を無視することができます (詳細なフック関数のパラメータについては以下を参照してください)。

少し混乱しています。「コンポーネントの VNode」とは、現在ディレクティブにバインドされている DOM 要素を指しますか?もしそうなら、現在の要素の状態が変化する限り更新はトリガーされますか?要素の表示と非表示を切り替えるには、v-show を使用します。

<p v-test v-show="show">これは別のテキストの段落です</p>
<button @click="show = !show">切り替え</button>

エクスポートデフォルト{
  データ () {
    戻る {
      表示: 真
    }
  }
}

デフォルトでは、bindとinsertがトリガーされます。ボタンをクリックして要素の表示を切り替えると、結果は次のようになります。

つまり、要素のスタイルが変更されると、update 関数と componentUpdated 関数がトリガーされます。 v-if を使用するとどのイベントがトリガーされますか?

<p v-test v-if="show">これは別のテキストの段落です</p>
<button @click="show = !show">切り替え</button>

結果:

v-if は DOM 要素を削除または再構築するため、unbind がトリガーされることがわかります。命令にバインドされた要素が破棄されると、命令の unbind イベントがトリガーされます。新しい表示では、引き続き bind と inserted がトリガーされます。

要約:

  • bind(): ディレクティブがHTML要素にバインドされたときにトリガーされます
  • 挿入(): 命令にバインドされた要素が親ノードに挿入されたときにトリガーされます
  • update(): ディレクティブにバインドされた要素の状態/スタイルまたはコンテンツ(ここでは要素にバインドされたVueデータを参照)が変更されたときにトリガーされます。
  • componentUpdated(): update() が実行されたときにトリガーされます
  • unbind(): ディレクティブにバインドされた要素がDOMから削除されたときにトリガーされます

以下にアプリケーションシナリオの例をいくつか示します。

1. 入力ボックスは自動的にフォーカスを取得します (公式の例)。

2. ドロップダウン メニューの外側をクリックしてメニューを非表示にします。

3. 入力したメールアドレスと電話番号を確認します。

上記の場合、プロジェクトを実行するときに代わりに他の方法を使用することもできますが、Vue カスタム命令を 1 か所で定義してグローバルに呼び出すことができるため、コードが簡潔で効率的になり、保守が容易になります。

ディレクティブの登録方法は、「フィルター」、「ミックスイン」、「コンポーネント」の登録方法と同じで、グローバル登録とローカル登録の 2 種類に分かれます。

3. グローバル指示

// 要素にランダムな背景を追加します <div v-bgcolor></div>
   
Vue.directive('bgcolor', {
    バインド: 関数(el, バインディング, vnode) {
        el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
    }
})

注意: 定義する場合、コマンド名の前に v- を付ける必要はありません。呼び出す場合は、コマンド名の前に v- を付ける必要があります。

4. ローカル指示

// データおよびメソッドと同じレベル メソッド: {},
ディレクティブ: {
    背景色:
         バインド: 関数(el, バインディング) {
            el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
        }
    }
}

個人的には、カスタム命令が使用されるようになったため、それらは普遍的かつ再利用可能であるはずなので、グローバル登録方法を使用することを好みます。したがって、コンポーネント内だけではなく、プロジェクト全体に対する指示を提供する方が価値があります。 1 か所でのみ使用される場合は、関数を直接追加するだけです。なぜこのような手間をかける必要があるのでしょうか?

5. パラメータ付きのカスタム命令

<div v-bgcolor='{color: 'オレンジ'}'></div>

Vue.directive('bgcolor', {
    バインド: 関数(el, バインディング) {
        el.style.backgroundColor = binding.value.color;
    }
})

6. 関数の省略形

バインドと更新時に同じ動作をトリガーし、他のフックを気にしない場合は、次のように記述できます。

// グローバル Vue.directive('bgcolor', function (el, binding) {
      el.style.backgroundColor = バインディング値
})

// ローカルディレクティブ: {
    bgcolor: (el, バインディング) => {
        el.style.backgroundColor = バインディング値  
    }
}

7. アプリケーション例

命令の作成方法とパラメータを理解したら、それを使用して 2 つの実用的なケースを作成します。

空白部分をクリックしてサブメニューを非表示にする機能は、命令によって実現されます。具体的なコードは次のとおりです。

// クリックアウトサイド.js
エクスポートデフォルト{
    バインド (el, バインディング) {
        const self = {} // イベントリスナーのアンバインドを容易にするためのプライベート変数を定義します。self.documentHandler = (e) => {
            if (el.contains(e.target)) { // ここで、バインドされた要素にクリック要素が含まれているかどうかを判定し、含まれている場合は false を返します。
            }
            if (binding.value) { // 命令内で値がバインドされているかどうかを判定します。binding.value(e) // 関数がバインドされている場合は、その関数を呼び出します。ここで、binding.value は handleClose メソッドです。}
            真を返す
        }
        document.addEventListener('click', self.documentHandler)
    },
    アンバインド (el) {
        //イベントリスニングを削除します document.removeEventListener('click', self.documentHandler)
        self.documentHandler を削除します
    }
}

コンポーネントでの使用:

<テンプレート>
    <div>
        <div v-show="isShow" v-clickoutside="handleClickOutside" @click="showOrHide">
            サブメニュー... 
        </div>
    </div>
</テンプレート>
​
<スクリプト>
    './js/clickOutside' から clickoutside をインポートします。
    
    エクスポートデフォルト{
        ……
        ディレクティブ: {
            クリックアウトサイド
        },
        データ() {
            戻る {
                isShow: true、
            };
        },
        メソッド: {
            ハンドル外側クリック() {
                this.isShow = false
            }
        }
    }
</スクリプト>

画像の読み込みを最適化するためのカスタム指示: 画像の読み込み中は、読み込みが完了するまで灰色の背景を使用してスペースを占有し、読み込み後すぐに画像が表示されます。

<テンプレート>
    <div>
        <!-- パラメータに URL アドレスを直接入力することはできません -->
        <img v-imgUrl='url' /> 
    </div>
</テンプレート>
​
<スクリプト>
    エクスポートデフォルト{
        データ () {
            戻る {
                url: '../src/assets/logo.png'
            }
        }
    }
</スクリプト>

// グローバル登録 Vue.directive('imgUrl', function (el, binding) {
    el.style.backgroundColor = '#FEFEFE' //背景色を設定 var img = new Image()
    img.src = binding.value // binding.value命令の後のパラメータ img.onload = function () {
        el.style.backgroundColor = ''
        el.src = バインディング値
    }
})

以上がVueのカスタム命令とその使い方の詳しい説明です。Vueについてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご覧ください!

以下もご興味があるかもしれません:
  • Vue はカスタム命令を通じて v 組み込み命令をレビューします (要約)
  • Vue組み込み命令の詳細な説明
  • Vueカスタム命令の詳細な説明
  • Vueのカスタム命令の詳細な説明
  • Vueのよく使われる組み込み命令の詳細な説明

<<:  MySQL ステートメントにおける IN と Exists の比較分析

>>:  Linux システムでの CPU 使用率が高い場合のトラブルシューティングのアイデアと解決策

推薦する

Windows 10 での MySQL 8.0.16 のインストールと設定のチュートリアル

この記事では、参考までにMySQL 8.0.16のインストールと設定方法のグラフィックチュートリアル...

Docker 用ビジュアル UI 管理ツール Portainer のインストールと使用方法の分析

Portainer は、ステータス表示パネル、アプリケーション テンプレートの迅速な展開、コンテナ ...

Docker-compose を使用して Django アプリケーションをオフラインでデプロイする方法

目次開発環境用のDocker-ceをインストールする開発環境用のDocker-composeをインス...

Vueの計算プロパティの詳細な説明

1. 計算属性とは何ですか? 簡単に言えば、計算された結果が属性に保存されるもので、キャッシュとして...

広告を閉じるための JavaScript カウントダウン

広告を閉じるまでのカウントダウンを実装するために JavaScript を使用するまだフロントエンド...

nginx で第 3 レベルドメイン名を設定する方法の例

問題の説明nginx を設定することで、異なるポートを介して異なる Web アプリケーションにアクセ...

Zabbixを介してデータベース接続情報といくつかの拡張機能をすばやく取得します

背景アプリケーション システムの数が増え続けると、当初はアラームを発していなかったアクティブ スレッ...

Nginx タイムアウト設定の詳細な説明

最近、プロジェクトで nginx を使用し、バックエンドで Java を使用しました。バックエンドで...

CSS フォント、テキスト、リストのプロパティの詳細な紹介

1. フォントのプロパティcolorは、div{color:red;}のようにテキストの色を指定しま...

mysql インストーラ ウェブ コミュニティ 5.7.21.0.msi インストール グラフィック チュートリアル

この記事の例では、Androidの9グリッド画像を表示するための具体的なコードを参考までに共有してい...

シェアしたい絶妙なApple風無料アイコン素材18セット

Apple マグカップのアイコンと追加機能 HD ストレージボックス – アドオンパックセイバースノ...

VMware 15 を使用して仮想マシンをインストールし、CentOS 8 を使用する詳細な手順

序文:現在、Linux と .Net Core を学習しており、クロスプラットフォームの知識を学んで...

Linuxブートサービスを起動する2つの方法

目次rc.local メソッドchkconfig メソッドrc.local メソッド1 まず自動的に...

MySQL 8.0.22 圧縮パッケージの完全なインストールと構成のチュートリアル図 (テスト済みで効果的)

1. zipインストールパッケージをダウンロードするMySQL サーバー 8.0.22 の圧縮パッ...

MySQL PXC は IST 送信のみで新しいノードを構築します (推奨)

需要シナリオ: 既存の PXC 環境には大量のデータがあります。新しく購入したサーバーをこのクラスタ...