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サーバーに接続する方法

推薦する

CSS 前景と背景の自動カラーマッチング技術の紹介 (デモ)

1. カラーマッチング効果のプレビュー下の GIF に示すように、ボタンの背景色が徐々に薄くなると...

MySQL8のパスワードを忘れた場合の簡単な解決策

序文MySQL データベースのパスワードを忘れると、データベースに正常にアクセスできなくなり、パスワ...

uniappの無痛トークンリフレッシュ方法の詳細な説明

フロントエンドがインターフェースを要求すると、バックエンドでインターフェースが定義されます。ステータ...

CSS3 でテキストの点滅効果を実現する 3 つの方法 サンプルコード

1. 透明度を変更してテキストを徐々に点滅させると、次のような効果が得られます。 <!DOCT...

SQL ファジー クエリ レポート: ORA-00909: パラメータの数が無効です。解決策

あいまいクエリにOracleデータベースを使用する場合、コンソール エラーは次の図に表示されます。理...

Reactベースのコンポーネントのカプセル化の実装手順

目次序文antd はどのようにしてコンポーネントをカプセル化するのでしょうか?ディバイダーコンポーネ...

数百万のデータに対して MySQL クエリを最適化する 4 つの方法

目次1. 時間が経つにつれて限界が遅くなる理由2. 百万データシミュレーション1. 従業員テーブルと...

バッチファイルを処理するLinuxの1行コマンドの詳細な説明

序文最良の方法は、あなたが思いつく最も速い方法ではないかもしれません。職場で一時的に使用するスクリプ...

GDBデバッグMySQL実戦ソースコードコンパイルとインストール

ソースコードをダウンロード git クローン https://github.com/mysql/my...

複数レベルの複雑な動的ヘッダーの avue-crud 実装例

目次序文バックグラウンドデータの結合フロントエンドデータ表示ページ効果表示Avue.js は、既存の...

開発効率の向上に役立つ 56 個の実用的な JavaScript ツール関数

目次1. デジタルオペレーション(1)指定された範囲内で乱数を生成する2. 配列操作(1)配列の順序...

特定のシンボルで複数の行と列に分割するMySQLの例

一部の障害コード テーブルでは、履歴またはパフォーマンス上の理由から、次の設計パターンが使用されます...

CSSポジションの5つの異なる値の使い方の詳細な説明

位置プロパティposition プロパティは、要素に使用する配置方法のタイプ (静的、相対的、固定、...

MySQL複合インデックスの詳細な研究

複合インデックス (結合インデックスとも呼ばれます) は、複数の列に対して作成されるインデックスです...

Web アプリ開発時間を短縮する 10 の時間を節約するヒント (グラフィカル チュートリアル)

今日の開発環境では、速いほど良いです。 「迅速なアプリケーション開発」、「アジャイル ソフトウェア開...