Vueのカスタムディレクティブの詳細なガイド

Vueのカスタムディレクティブの詳細なガイド

1. カスタム指示とは何ですか?

v- で始まるインライン属性はすべて命令です。異なる命令によって、異なる機能を完了または実装し、通常の DOM 要素に対して低レベルの操作を実行できます。これは、カスタム命令が使用されるときです。コア関数 (v-model および v-show) のデフォルトの組み込み命令に加えて、Vue ではカスタム命令を登録することもできます。

このコマンドを使用する方法はいくつかあります。

// コマンドをインスタンス化しますが、このコマンドにはパラメータ `v-xxx` がありません
 
// -- 値を命令 `v-xxx="value"` に渡します  
 
// -- `v-html="'<p>Content</p>'"` などの文字列をディレクティブに渡します。
`v-xxx="'文字列'"` 
 
// -- `v-bind:class="className"` などのパラメータ (`arg`) を渡します
`v-xxx:arg="値"` 
 
// -- 修飾子を使用する (`modifier`)
`v-xxx:arg.modifier="値"` 

2. 指示をカスタマイズする方法

カスタム ディレクティブの登録は、グローバルまたはローカルで行うことができます。

グローバル登録は主にVue.directiveメソッドを使用して登録されます

Vue.directiveの最初のパラメータはディレクティブの名前(v-プレフィックスなし)であり、2番目のパラメータはオブジェクトデータまたはディレクティブ関数になります。

// グローバルカスタムディレクティブ `v-focus` を登録します
Vue.directive('focus', {
  // バインドされた要素が DOM に挿入されると...
  挿入: 関数 (el) {
    // 要素にフォーカス el.focus() // ページが読み込まれた後に入力ボックスに自動的にフォーカスする小さな関数}
})

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

ディレクティブ: {
  集中:
    // 挿入された命令の定義: function (el) {
      el.focus() // ページが読み込まれた後に入力ボックスに自動的にフォーカスする小さな関数}
  }
}

次のように、テンプレート内の任意の要素に新しい v-focus プロパティを使用できます。

<入力vフォーカス />

フック機能

カスタム命令にも、コンポーネントのようなフック関数があります。

  • bind: ディレクティブが要素に最初にバインドされるときに 1 回だけ呼び出されます。ここで、1回限りの初期化設定を実行できます
  • 挿入: バインドされた要素が親ノードに挿入されるときに呼び出されます (親ノードが存在することを保証するだけで、必ずしもドキュメントに挿入されるわけではありません)
  • update: コンポーネントの VNode が更新されたときに呼び出されますが、子 VNode が更新される前に発生することもあります。命令の値は変更されている場合と変更されていない場合があります。ただし、更新前と更新後の値を比較することで、不要なテンプレートの更新を無視することができます。
  • componentUpdated: 命令が配置されているコンポーネントのVNodeとその子VNodeがすべて更新された後に呼び出されます。
  • unbind: 命令が要素からアンバインドされたときに一度だけ呼び出されます

すべてのフック関数のパラメータは次のとおりです。

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

`name`: v- プレフィックスを除いたディレクティブの名前。

`value`: ディレクティブのバインディング値。たとえば、v-my-directive="1 + 1" の場合、バインディング値は 2 です。

`oldValue`: ディレクティブ バインディングの前の値。update フックと componentUpdated フックでのみ使用できます。値が変更されたかどうかに関係なく使用できます。

`expression`: 文字列としてのディレクティブ式。たとえば、v-my-directive="1 + 1" の場合、式は "1 + 1" になります。

`arg`: コマンドに渡されるパラメータ(オプション)。たとえば、v-my-directive:foo の場合、パラメーターは "foo" です。

`modifiers`: 修飾子を含むオブジェクト。たとえば、v-my-directive.foo.bar では、修飾子オブジェクトは { foo: true, bar: true } です。

`vnode`: Vue コンパイルによって生成された仮想ノード

`oldVnode`: 以前の仮想ノード。update および componentUpdated フックでのみ使用可能

el を除き、他のすべてのパラメータは読み取り専用であり、変更しないでください。フック間でデータを共有する必要がある場合は、要素のデータセットを介して共有することをお勧めします。

例えば:

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
<スクリプト>
    Vue.directive('demo', 関数(el, バインディング) {
    console.log(binding.value.color) // "白"
    console.log(binding.value.text) // "こんにちは!"
    })
</スクリプト>

3. 応用シナリオ

カスタム コンポーネントを使用すると、日常のシナリオの一部に対応できます。カスタム コンポーネントの例をいくつか示します。

  • 安定
  • 画像の遅延読み込み
  • ワンクリックコピー機能

入力ボックスの手ぶれ補正

この場合、Vスロットルカスタム命令を設定して手ぶれ防止を実現する

例えば:

// 1. v-throttleカスタムディレクティブを設定する Vue.directive('throttle', {
  バインド: (el, バインディング) => {
    let throttleTime = binding.value; // 手ぶれ補正時間if (!throttleTime) { // ユーザーが手ぶれ補正時間を設定していない場合、デフォルトは2秒です
      スロットル時間 = 2000;
    }
    cbFun を実行します。
    el.addEventListener('クリック', イベント => {
      if (!cbFun) { // 最初の実行 cbFun = setTimeout(() => {
          cbFun = null;
        }, スロットル時間);
      } それ以外 {
        イベント && event.stopImmediatePropagation();
      }
    }、 真実);
  },
});
// 2. ボタン タグに v-throttle カスタム命令を設定します <button @click="sayHello" v-throttle>Submit</button>

画像の遅延読み込み

画像の遅延読み込みを完了するためにv-lazyカスタムコンポーネントを設定する

定数LazyLoad = {
    // インストールメソッド install(Vue,options){
       // image の代わりに画像を読み込みます let defaultSrc = options.default;
        Vue.directive('lazy',{
            バインド(el,バインディング){
                LazyLoad.init(el、binding.value、defaultSrc);
            },
            挿入された(el){
                // 互換性処理 if('InterpObserver' in window){
                    LazyLoad.observe(el);
                }それ以外{
                    LazyLoad.listenerScroll(el);
                }
                
            },
        })
    },
    // 初期化 init(el,val,def){
        // src は実際の src を格納します
        el.setAttribute('src',val);
        // src を読み込み画像に設定します el.setAttribute('src',def);
    },
    // InterpObserverを使用してelを監視する
    観察する{
        io = new InterpObserver(エントリ => {
            realSrc = el.dataset.src; とします。
            エントリ[0]が交差している場合
                if(realSrc){
                    el.src = 実Src;
                    el.removeAttribute('src');
                }
            }
        });
        io.observe(el);
    },
    // スクロールイベントをリッスンする listenerScroll(el){
        ハンドラをLazyLoad.throttle(LazyLoad.load,300);
        LazyLoad.load(el);
        window.addEventListener('スクロール',() => {
            ハンドラ(el);
        });
    },
    // 実画像を読み込む load(el){
        windowHeight = document.documentElement.clientHeight とします。
        elTop を el.getBoundingClientRect().top とします。
        elBtm = el.getBoundingClientRect().bottom; とします。
        realSrc = el.dataset.src; とします。
        if(elTop - windowHeight<0&&elBtm > 0){
            if(realSrc){
                el.src = 実Src;
                el.removeAttribute('src');
            }
        }
    },
    // スロットル(fn,遅延){
        タイマーを設定します。 
        prevTime を設定します。
        関数(...引数)を返す{
            currTime = Date.now() とします。
            コンテキストを this とします。
            前の時刻が現在の時刻と等しい場合、前の時刻は現在の時刻と等しくなります。
            タイマーをクリアします。
            
            (現在の時刻 - 前の時刻 > 遅延) の場合 {
                前回の時刻 = 現在の時刻;
                fn.apply(コンテキスト、引数);
                タイマーをクリアします。
                戻る;
            }
 
            タイマー = setTimeout(関数(){
                前の時刻 = Date.now();
                タイマー = null;
                fn.apply(コンテキスト、引数);
            }、遅れ);
        }
    }
 
}
デフォルトのLazyLoadをエクスポートします。

ワンクリックコピー機能

'ant-design-vue' から { Message } をインポートします。
 
const vCopy = { //
  /*
    バインドフック関数は、初めてバインドするときに呼び出され、初期化設定を行うために使用できます。el: 操作する DOM オブジェクト。value: 命令に渡される値、つまりコピーしたい値*/
  バインド(el, { 値 }) {
    el.$value = value; // この値は他のフック関数で使用されるため、渡された値を格納するためにグローバルプロパティを使用します。el.handler = () => {
      if (!el.$value) {
      // 値が空の場合、プロンプトを表示します。ここで使用しているプロンプトは ant-design-vue のプロンプトです。自由に使用できます。Message.warning('No copy content');
        戻る;
      }
      // textarea タグを動的に作成します。const textarea = document.createElement('textarea');
      // iOS 上でキーボードが自動的に表示されないようにするために textarea を読み取り専用に設定し、textarea を表示領域から移動します。textarea.readOnly = 'readonly';
      textarea.style.position = '絶対';
      textarea.style.left = '-9999px';
      // コピーする値を textarea タグの value 属性に割り当てます。textarea.value = el.$value;
      // 本文にテキストエリアを挿入します。 document.body.appendChild(textarea);
      // 値を選択してコピーします textarea.select();
      // textarea.setSelectionRange(0, textarea.value.length);
      const result = document.execCommand('コピー');
      if (結果) {
        Message.success('コピーが成功しました');
      }
      document.body.removeChild(テキストエリア);
    };
    // クリック イベント (いわゆるワンクリック コピー) をバインドします。el.addEventListener('click', el.handler);
  },
  // 入力値が更新されると、componentUpdated(el, { value }) がトリガーされます。
    el.$value = 値;
  },
  // 命令が要素からアンバインドされたら、イベントバインディングを削除します unbind(el) {
    el.removeEventListener('click', el.handler);
  },
};
 
デフォルトの vCopy をエクスポートします。

ドラッグ

<div ref="a" id="bg" v-drag></div>

  ディレクティブ: {
    ドラッグ: {
      バインド() {},
      挿入(el) {
        el.onmousedown = (e) => {
          x = e.clientX - el.offsetLeft とします。
          y = e.clientY - el.offsetTop とします。
          ドキュメント.onmousemove = (e) => {
            xx = e.clientX - x + "px" とします。
            yy = e.clientY - y + "px" とします。
            el.style.left = xx;
            el.style.top = yy;
          };
          el.onmouseup = (e) => {
            ドキュメント.onmousemove = null;
          };
        };
      },
    },
  },

ドラッグ アンド ドロップの指示、ページの透かし、権限の検証など、カスタム コンポーネントの適用シナリオは多数あります。

要約する

Vue のカスタム ディレクティブに関するこの記事はこれで終わりです。Vue のカスタム ディレクティブに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vueカスタム命令の詳細な説明
  • Vueカスタムディレクティブの詳細
  • Vueカスタムコピー命令v-copy関数の実装

<<:  MySQL テーブルがロックされているかどうかを照会する方法

>>:  MySQL 結合クエリ構文と例

推薦する

ウェブページのアクセス速度に関する主な問題と解決策

<br />ウェブサイトのアクセス速度はウェブサイトのトラフィックに直接影響を及ぼし、ウ...

MySQL SELECT文の実行方法

MySQL Select ステートメントはどのように実行されますか?最近、Geek Time で D...

Mysql InnoDBとMyISAMの違いの分析

MySQL は、myisam、innodb、memory、archive、example など、多く...

JavaScript のデシェイクとスロットリングの例

目次安定スロットル: 手ぶれ防止: 一定時間内に最後のタスクのみを実行します。スロットル: 一定期間...

一般的な Nginx のテクニックと例の概要

1. 複数サーバーの優先順位たとえば、各サーバー ブロックがポート 80 をリッスンする場合、www...

MySQLのデッドロックチェック処理の通常の方法

通常、デッドロックが発生すると、重みが最も小さい接続が強制終了され、ロールバックされます。ただし、最...

MySQL データ型における DECIMAL の使用法の詳細な説明

MySQL データ型における DECIMAL の使用法の詳細な説明MySQL のデータ型には、INT...

CSS 表示属性のインラインブロックレイアウト実装の詳細な説明

CSS 表示プロパティ注: !DOCTYPE が指定されている場合、Internet Explore...

Reactはラジオコンポーネントのサンプルコードを実装します

この記事の目的は、最も明確な構造を使用していくつかのコンポーネントの基本機能を実装することです。皆さ...

SSHのssh-keygenコマンドの基本的な使い方の詳細な説明

SSH 公開鍵認証は、SSH 認証方式の 1 つです。 SSH パスワードフリーのログインは公開鍵認...

Docker ベースの nginx ファイル サーバーを構築する方法と手順

1. このマシンに新しい設定ファイルdocker_nginx.confを作成します。 サーバー{ 7...

Tomcat でタイムアウトしたセッションを監視および削除する方法

序文偶然、30 分の Tomcat セッション時間は、セッションが作成された後、30 分間のみ有効で...

docker で Apollo をデプロイする詳細なチュートリアル

1. はじめにここでは apollo について詳しく説明しません。公式サイト https://git...

Vueは州、都市、地区のカスケード選択を実現します

最近、省、市、地区のカスケード選択効果を実装する必要があります。省、市、地区のデータはすべてローカル...

CSSマウスを画像の上に置いたときにマスクレイヤー効果を追加する実装

まず効果を見てみましょう: マウスを画像の上に移動すると、影の効果とテキスト/アイコンが追加されます...