Vue 3 カスタムディレクティブ開発の概要

Vue 3 カスタムディレクティブ開発の概要

指令とは何ですか?

Angular と Vue はどちらもディレクティブの概念を持っており、これは通常「指示」と訳されます。

コンピュータ技術において、命令とは、命令セット アーキテクチャによって定義される単一の CPU 操作です。より広い意味では、「命令」は、バイトコードなどの実行可能プログラムの要素の任意の表現になります。

では、フロントエンドフレームワーク Vue における「ディレクティブ」とは一体何であり、その機能は何でしょうか?

Vue 開発では、テンプレート内で v-model や v-show などの v- で始まるキーワードをよく使用します。これらのキーワードは、Vue フレームワークに組み込まれた命令です。 v-model を使用すると、DOM とデータのバインディングを実現できます。v-show を使用すると、DOM 要素の表示を制御できます。つまり、これらのテンプレートのタグを使用することで、フレームワークは DOM 要素に対して指定された処理を実行し、DOM が変更された後にフレームワークは指定されたデータを同時に更新することができます。ディレクティブは Vue MVVM の基盤の 1 つです。

指導の使用シナリオ

組み込み命令の使用に加えて、Vue はカスタム命令もサポートしています。カスタム命令を通じて、次のシナリオを実装できます。

基本的な DOM 操作。コンポーネント内の一部の処理を既存の命令で実装できない場合は、カスタム命令を使用して実装できます。たとえば、コンポーネントの透かしや自動フォーカスなどです。 ref を使用して DOM 操作を取得する場合と比較すると、命令をカプセル化すると MVVM アーキテクチャに沿ったものとなり、M と V は直接相互作用しません。

<p v-highlight="'yellow'">このテキストを明るい黄色で強調表示します</p>

複数のコンポーネントで利用可能な共通の操作は、コンポーネントを使用することで再利用できます。同様に、関数もコンポーネント上で再利用できます。たとえば、スペルチェックや画像の遅延読み込みなどです。コンポーネントを使用する場合、スペルチェックが必要な入力コンポーネントにラベルを追加するだけで、コンポーネントにスペルチェック機能を挿入できます。異なるコンポーネントに新しいスペルサポート機能をカプセル化する必要はありません。

Vue 3でディレクティブをカスタマイズする方法

Vue はディレクティブのグローバルおよびローカル登録をサポートしています。

グローバル登録は、アプリ インスタンスのディレクティブ メソッドを通じて登録されます。

app = createApp(App) を作成します。
app.directive('ハイライト', {
beforeMount(el, バインディング, vnode) {
el.style.background = バインディング値
}
})

ローカル登録は、コンポーネントにディレクティブ属性を設定することによって行われます。

エクスポートデフォルトdefineComponent({
名前: "Webデザイナー",
コンポーネント:
デザイナー、
},
ディレクティブ: {
ハイライト:
beforeMount(el, バインディング, vnode) {
el.style.background = バインディング値;
},
},
},
});

登録されたコンポーネントには、一意である必要があるコンポーネントの名前と、コンポーネントの実装オブジェクトが含まれます。登録後は、任意の要素で使用できます。

<p v-highlight="'yellow'">このテキストを明るい黄色で強調表示します</p>

カスタム コンポーネントは、Vue が提供するフック関数を実装します。Vue 3 では、フック関数のライフ サイクルはコンポーネントのライフ サイクルに似ています。

  • created - 要素が作成された後に、その属性とイベントが有効になる前に呼び出されます。
  • beforeMount - ディレクティブが要素に最初に添付されるときに 1 回だけ呼び出されます。
  • マウント - 要素が親要素に挿入されたときに呼び出されます。
  • beforeUpdate: 要素が更新される前に呼び出されます
  • 更新済み - 要素またはその子要素が更新された後に呼び出されます。
  • beforeUnmount: 要素がアンマウントされる前に呼び出されます。
  • unmounted - コマンドがアンマウントされたときに呼び出され、一度だけ呼び出されます

各フック関数には次のパラメータがあります。

  • el: 命令がバインドされている要素。DOMを直接操作するために使用できます。
  • バインディング: 次の属性を含むデータオブジェクト

インスタンス: 現在のコンポーネントのインスタンス。一般的に、命令はコンポーネントから独立していることが推奨されます。コンポーネントコンテキストの ViewModel を使用する必要がある場合は、ここから取得できます。
値: 命令の値。上記の例では「黄色」
oldValue: 命令の前の値。beforeUpdate および Updated では、値と同じになる場合があります。
arg: v-on:click の click など、命令に渡される引数。
modifiers: 修飾子を含むオブジェクト。たとえば、v-on.stop:clickは{stop:true}のオブジェクトを取得できます。

  • vnode: Vueコンパイルによって生成された仮想ノード、
  • prevVNode: 更新中の前の仮想ノード

Vue 2 ディレクティブのアップグレード

このディレクティブは Vue3 の重大な変更であり、ディレクティブのフック関数の名前と番号が変更されました。 Vue3 では、ディレクティブ用の関数がさらに作成されます。関数名はコンポーネントのライフサイクルと一致しているため、理解しやすくなっています。

変更点は以下のとおりです

もう 1 つの変更点は、コンポーネント コンテキスト オブジェクトを取得する方法です。一般的に、命令とコンポーネント インスタンスは互いに独立していることが推奨されます。カスタム命令内からコンポーネント インスタンスにアクセスする場合、命令をカプセル化する必要がなく、命令がコンポーネント自体の機能であることを意味する場合があります。ただし、コンポーネント インスタンスを取得する必要があるシナリオもあります。

Vue 2 で vnode パラメータで取得する

bind(el, バインディング, vnode) {
  定数 vm = vnode.context
}

Vue 3のバインディングパラメータを通じて取得する

マウント(el, バインディング, vnode) {
  const vm = バインディングインスタンス
}

Vue 3 カスタムディレクティブの例 – 入力スペルチェック

ここでは、プラグインを使用して命令を挿入します。

新しい SpellCheckPlugin.ts を作成し、プラグインを宣言し、プラグインのインストールメソッドに指示を挿入します。

'vue' から { App } をインポートします

 関数 SpellCheckMain(app: App, オプション: any) {
//
}

 エクスポートデフォルト{
    インストール:SpellCheckMain
}

SpellCheckMain メソッドは、コンポーネントとスペル チェック メソッドを実装します。特定のスペル チェック ルールは、ビジネスに応じて、または他のプラグイン メソッドを使用して実装できます。

関数 SpellCheckMain(app: App, オプション: any) {
    const SpellCheckAttribute = "スペルチェック属性";

     SpellCheckTimer: Map<文字列、数値> = new Map();
    チェッカーIDを0にします。
    関数 checkElement(el: HTMLElement) {
        attr = el.getAttribute(SpellCheckAttribute); とします。
        (属性)の場合{
            タイムアウトをクリアします(SpellCheckTimer.get(attr));
            タイマーをsetTimeout(() => { checkElementAsync(el) }, 500 に設定します。
            SpellCheckTimer.set(属性、タイマー)
        }
    }
    関数 checkText(単語?: 文字列 | null): [文字列?] {
        if (!単語) {
            戻る [];
        }
        errorWordList: [文字列?] = [];
        試す {
            wordsList を words.match(/[a-zA-Z]+/ig) とします。
            wordsList?.forEach((単語) => {
                if (!checkWord(単語)) {
                    errorWordList.push(単語);
                }
            })
        }
        キャッチ{

         }
        errorWordList を返します。
    }
    関数 checkWord(テキスト: 文字列) {
        //スペルチェックをシミュレートします。ここでは他のチェックライブラリを使用します。 return text.length > 6 ? false : true;
    }
    関数 checkElementAsync(el: HTMLElement) {

         text = (el as HTMLInputElement).value || el.innerText; とします。
        結果 = checkText(テキスト) とします。

         attr = el.getAttribute(SpellCheckAttribute); とします。
        (!属性)の場合{
            戻る;
        }

         if (結果 && 結果.長さ) {
            el.style.background = "ピンク"
            div = document.getElementById(attr); とします。
            場合 (!div) {
                div = document.createElement("div");
                div.id = 属性;
                div.style.position = "絶対"
                div.style.top = "0px"
                div.style.left = el.clientWidth + "px"

                 親要素の場合
                    el.parentElement.style.position = "相対"
                    el.parentElement.lastChild が el の場合
                        el.parentElement.appendChild(div);
                    }
                    それ以外 {
                        el.parentElement.insertBefore(div, el.nextSibling);
                    }
                }
            }
            div.innerHTML = result.length.toString() + " - " + result.join(",");
        } それ以外 {
            el.style.background = "";

             div = document.getElementById(attr); とします。
            (div)の場合{
                div.innerHTML = ""
            }
        }

         console.log(結果)
    }

     app.directive('スペルチェック', {
        作成された() {
            console.log("作成済み", 引数)
        },
        マウント: 関数 (el, バインディング, vnode, oldVnode) {

             console.log("マウント済み", 引数)
            //親のチェッカーIDを設定する
            attr = "spellcheck-" + (checkerId++) とします。
            el.setAttribute(スペルチェック属性、属性);
            console.log("属性", 属性)

             if (el.tagName.toUpperCase() === "DIV") {
                el.addEventListener("ぼかし", 関数() {
                    チェック要素(el)
                }、 間違い);
            }
            if (el.tagName.toUpperCase() === "入力") {
                el.addEventListener("keyup", 関数() {
                    チェック要素(el)
                }、 間違い);
            }
            // el.addEventListener("focus", 関数() {
            // チェック要素(el)
            // }、 間違い);
        },
        更新: 関数 (el) {
            console.log("componentUpdated", 引数)
            要素をチェックします(el);
        },
        アンマウント: 関数 (el) {
            console.log("マウント解除", 引数)

             attr = el.getAttribute(SpellCheckAttribute); とします。
            (属性)の場合{
                div = document.getElementById(attr); とします。
                (div)の場合{
                    div.remove();
                }
            }
        }
    })
}

main.ts でのプラグインの使用

/// <参照パス="./vue-app.d.ts" />
'vue' から {createApp} をインポートします。
'./App.vue' からアプリをインポートします。
'./router' からルーターをインポートします
'./plugins/SpellCheckPlugin' から SpellCheckPlugin をインポートします。

 app = createApp(App) を作成します。
app.use(スペルチェックプラグイン)
app.use(ルーター).mount('#app') を実行します。

コンポーネント内で直接ディレクティブを使用するだけです

<テンプレート>
  <div ref="ssHost" スタイル="幅: 100%; 高さ: 600px"></div>
  <div><div ref="fbHost" スペルチェック v-spell-check="true" contenteditable="true" スペルチェック="false" style="border: 1px solid #808080;width:600px;"></div></div>
  <div><input v-model="value1" v-spell-check スペルチェック="false" style="width:200px;" /></div>
</テンプレート>

ユーザーのスペル入力をチェックする機能をベースに SpreadJS の使用を組み合わせると、効果は次のようになります。

以上がVue 3カスタムディレクティブ開発の詳細な概要です。Vue 3カスタムディレクティブ開発の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vue 3.0 カスタムディレクティブの使い方
  • Vueカスタム命令とその使用方法の詳細な説明
  • Vueカスタムディレクティブを使用してドラッグアンドドロッププラグインを構築する方法
  • Vue.js ソースコード解析のカスタム手順の詳細な説明
  • ボタンの権限判定を実装するためのVueカスタムv-has命令
  • Vue の基本的な手順の例のグラフィック説明
  • Vue3.0 カスタム命令(命令)知識の要約
  • 8つの非常に実用的なVueカスタム指示
  • Vueのカスタム命令の詳細な説明
  • Vue命令の実装原理の分析

<<:  DockerとFastDFSのインストールコマンドと使い方の詳しい説明

>>:  SSHトンネルを使用してMySQLサーバーに接続する方法

推薦する

Websocket+Vuexはリアルタイムチャットソフトウェアを実装します

目次序文1. 効果は図の通りです2. 具体的な実施手順1. Vuexの紹介2.webscoked実装...

CSS を使用してプログレスバーと順序プログレスバーを実装する例

この半月、期末試験の準備にかなりのエネルギーを費やしました。今日はしっかり復習するべきだったのですが...

Dockerはローカルディレクトリとデータボリュームコンテナ操作をマウントします

1. DockerはローカルディレクトリをマウントしますDocker は、ホスト上のディレクトリをイ...

Docker に MySQL と Redis をインストールする方法

この記事はCentOS 7.3システム環境をベースに、MySQLとRedisのインストールと使用につ...

HTMLはマーキーを使用してテキストを左右にスクロールします

コードをコピーコードは次のとおりです。 <本文> //マーキーの助けを借りて<MA...

Dockerコンテナアプリケーションログの表示方法

docker アタッチコマンドdocker attach [options] 容器実行中のコンテナに...

MySQL UPDATE ステートメントの「典型的な」落とし穴

目次1. 問題のあるSQL文たとえば、次の図のような質問をした人がいました。 問題は次のように要約で...

Windows プラットフォームでの MySQL のインストールと設定方法と注意事項

2.1、msiインストールパッケージ2.1.1、インストール特に重要なのは、インストール前に、元の ...

よく使用される入力テキストボックスの内容は自動的に垂直方向に中央揃えされ、クリックするとデフォルトのプロンプトテキストは空になります。

3つの機能: 1. コンテンツの垂直方向の自動中央揃え2. デフォルトのプロンプトテキストは灰色で表...

トランザクションとロックを表示するための MySQL の一般的なステートメント

データベース内のトランザクションとロックを表示するための一般的なステートメントトランザクションの待機...

CSS3 で z-index が効かない問題の解決方法

最近、CSS3 と js の組み合わせを作成したのですが、z-index が有効にならないケースが多...

更新とデータ整合性処理のためのMySQLトランザクション選択の説明

MySQL のトランザクションはデフォルトで自動的にコミットされます (autocommit = 1...

CSS3 フレックスレイアウトを使用して要素を均等に分散するサンプルコード

この記事では主に、CSS3 フレックスレイアウトを使用して要素を均等に配置する方法を紹介します。自分...

Docker実践: Pythonアプリケーションのコンテナ化

1. はじめにコンテナはサンドボックス メカニズムを使用して相互に分離します。コンテナ内にデプロイさ...

Webpack プロジェクトでローダー プラグインをデバッグする方法

最近、webpackの使い方を学んでいたときに、webpack-replace-loaderの設定正...