Vueカスタムディレクティブを使用してドラッグアンドドロッププラグインを構築する方法

Vueカスタムディレクティブを使用してドラッグアンドドロッププラグインを構築する方法

HTML5 のドラッグ アンド ドロップ機能は誰もが知っていますが、これを使用するとドラッグ アンド ドロップ機能を簡単に実装できます。たとえば、一部の選択操作のシナリオでは、マウスでクリックするよりもドラッグの方がユーザーにとって受け入れやすく、理解しやすいです。今日はこの機能を使用し、それを Vue のカスタム命令と組み合わせて、シンプルでありながら実用的なドラッグ アンド ドロップ プラグインを実装します。

なぜプラグインと呼ばれるのでしょうか?私たちの目標は Vue コンポーネントを開発することではなく、2 つの Vue カスタム命令を開発することであり、最終的にはこれら 2 つのカスタム命令が ES6 クラスにカプセル化され、実際のプロジェクトに導入するときに簡単に使用できるようになります。

ほとんどのドラッグ アンド ドロップ シナリオでは、選択した要素を領域 A から領域 B にドラッグ アンド ドロップします。ここでは 2 つの概念が関係しています。1 つはドラッグ可能、もう 1 つは配置可能という概念です。選択した要素はドラッグ可能で、ターゲット領域 (コンテナー) は配置可能である必要があります。

ドラッグ可能な vue コンポーネントを開発する場合、またはドロップ可能なコンポーネントを開発する場合、ドラッグ アンド ドロップできるのはこのコンポーネントのみです。この時点で、要件が変更され、別のコンポーネントでドラッグ アンド ドロップをサポートする必要がある場合は、他のコンポーネントのドラッグ アンド ドロップ コードを記述する必要があります。あるいは、他のプロジェクトでもドラッグ アンド ドロップ機能が必要になり、それを再開発する必要があるかもしれません。これはメンテナンスや再利用に役立ちませんが、Vue のカスタム命令はこの問題をうまく解決するのに役立ちます。このコンポーネント (要素) をドラッグ アンド ドロップ可能にするには、コンポーネント (通常の DOM 要素を含む) にカスタム命令を追加するだけで、柔軟に使用できるようになります。

コア機能のデフォルトの組み込みディレクティブ (v-model および v-show) に加えて、Vue ではカスタム ディレクティブを登録することもできます。 Vue 2.0 では、コードの再利用と抽象化の主な形式はコンポーネントであることに注意してください。ただし、場合によっては、通常の DOM 要素に対して低レベルの操作を実行する必要があり、このような場合はカスタム命令が使用されます。

要約すると、この記事の目標は、次の 2 つのカスタム手順を完了することです。

  • v-dragはコンポーネントをドラッグ可能にする
  • v-dropはコンポーネントをドロップ可能にする

目標は明確です。さあ始めましょう!これら 2 つの命令をどのコンポーネントでも機能させるには、Vue グローバル ディレクティブを登録する必要があります。

Vue.directive('ドラッグ', {
   bind(el, バインディング, vnode){
        // ディレクティブが最初に要素にバインドされたときに 1 回だけ呼び出されます。
        //ここで、1 回限りの初期化セットアップを実行できます。
    }
})
Vue.directive('drop', {
   bind(el, バインディング, vnode){
        //
    }
})

プロジェクトが vue-cli を使用してビルドされている場合は、main.js の vue 初期化の上にこのコードを記述できます。

まず、ドラッグ ディレクティブの bind フックにコードを記述します。bind は 1 回だけ呼び出され、ディレクティブが最初に要素にバインドされるときに呼び出されるため、bind フックを使用します。このディレクティブの目的は、コンポーネント(要素)をドラッグ可能にすることなので、elのdraggableをtrueに設定します。

el.draggable = true;
el.ondragstart = (イベント)=>{
  event.dataTransfer.setData("Text", "あなたのデータ...");
}

要素がドラッグされると、まず ondragstart イベントがトリガーされます。通常、このイベントでイベントの dataTransfer のドラッグ データを設定します。その目的は、要素がドロップされたときに、ターゲット コンテナーがドラッグされたデータを取得できるようにすることです。ドラッグ アンド ドロップでデータを転送できない場合は意味がありません。上記のコードは、ドラッグ データを設定するために dataTransfer の setData メソッドを呼び出します。setData のパラメーター 1 はデータの種類を示し、パラメーター 2 は転送されるデータを示します。

残念ながら、ドラッグデータは現在文字列のみをサポートしています。複雑なオブジェクトを渡したい場合は、データをシリアル化することができます。

次に、ドロップ ディレクティブのバインド フックのコードを記述します。このディレクティブの目的は、コンポーネント (要素) をドロップ可能にすることなので、要素の ondragover (ドラッグ オーバー イベント) と ondrop (ドロップ イベント) のハンドラーを記述する必要があります。これら 2 つのハンドラーは、イベントのデフォルトの動作を防ぐ必要があります。

el.ondragover = (イベント)=>{
  event.preventDefault(); //デフォルトの動作を防止する}
el.ondrop = (イベント)=>{
  イベントをデフォルトにしない();
  let dragData = event.dataTransfer.getData('Text'); //ドラッグデータを取得する}

ドラッグ開始イベントで設定されたドラッグ データは、event.dataTransfer の getData メソッドを通じて取得できます。

これで、これらの 2 つの命令を任意のコンポーネントに追加できます。v-drag を持つコンポーネントはドラッグでき、v-drop を持つコンポーネントは配置してドラッグ データを受け取ることができます。

<MyComponent を v-drag></MyComponent>

<MyContainer v-drop></MyContainer>

新たな問題が発生します。データを転送するためにドラッグ操作を実行します。ただし、データ転送の初期段階はカスタム命令ドラッグのバインド フックで実行され、データ転送の受信段階はドロップのバインド フックで実行されます。では、データはどこから来るのでしょうか。どこに行くの?当然、データはコンポーネントから取得され、別のコンポーネントにも渡される必要があります。そうしないと、vue コンポーネントにディレクティブを記述する意味がありません。

幸いなことに、カスタム命令のフック関数は、コンポーネントにアクセスするための最も簡単で効果的な方法を提供します。それは、フック関数の 3 番目のパラメーター vnode です。vnode には、componentInstance と呼ばれる属性があります。この componentInstance は、カスタム命令のホスト、つまり vue コンポーネント インスタンスです。

次のステップは簡単です。v-drag が追加されたコンポーネントのドラッグ データを取得するためのインターフェイスと、v-drop が追加されたコンポーネントのドラッグ データを受信するためのインターフェイスを定義するだけです。 Vue コンポーネントはインターフェースの定義をサポートしていませんが、2 つのメソッド名に同意して、コンポーネントのメソッドに実装することができます。

//カスタム コンポーネントの内部メソッド:{
  getDragData(){ //getDragData は、コンポーネントのドラッグ データを取得するためのインターフェイス メソッドであることに同意します。 return this.id; //このコンポーネントがドラッグされたときに、ID を渡す必要があると想定します。}
  setDragData(data){ //setDragData は、コンポーネントがドラッグ データを受け取るためのインターフェイス メソッドとして承認されています。this.appendNewChildById(data); //このコンポーネントは、新しい要素を生成するために ID を受け取ると想定します}
}

次に、ドラッグ データ コードを設定して渡すようにカスタム命令を書き直します。

dragValue を "" にします。
if(vnode.componentInstance.getDragData != 未定義){
  ドラッグ値 = vnode.componentInstance.getDragData();
}
event.dataTransfer.setData("テキスト", dragValue);

v-drop ディレクティブの ondrop イベント

dragValue を event.dataTransfer.getData('Text') にします。
if(vnode.componentInstance.setDragData != 未定義){
  vnode.componentInstance.setDragData(ドラッグ値);
}

インターフェース制約がないとコンポーネントがこれらのメソッドを実装しない可能性があるため、コンポーネントのインターフェース メソッドにアクセスするときに if チェックを追加しました。

さて、ここでは、コンポーネントをドラッグ アンド ドロップするためのカスタム命令を完全に実装しました。シンプルですが、非常に実用的で柔軟性があり、基本的に日常のドラッグ アンド ドロップのニーズを満たすことができます。プロセス全体をまとめてみましょう。

  • グローバルディレクティブv-dragとv-dropをカスタマイズする
  • ドラッグされたコンポーネントは、データを取得するためのインターフェースメソッドを実装する必要がある
  • 配置する必要があるコンポーネントは、データを受信するためのインターフェースメソッドを実装します
  • ドラッグコマンドはコンポーネントのインターフェースメソッドにアクセスしてデータを取得します。
  • ドロップ命令はコンポーネントのインターフェースメソッドにアクセスしてデータを渡す

グローバル カスタム ディレクティブの関連コードを es6 クラスにカプセル化し、別の js ファイルとしてプロジェクトに配置するか、npm に公開してから、このクラスを main.js にインポートし、静的初期化メソッドを呼び出して、グローバル ディレクティブの登録を完了します。この方法では、プロジェクト内のどのコンポーネントでも v-drag と v-drop を使用できます。上記でまとめた 5 つの手順のうち、実装する必要があるのは 2 番目と 3 番目の手順だけです。

上記は、vue カスタム命令を使用してドラッグ アンド ドロップ プラグインを構築する方法の詳細です。ドラッグ アンド ドロップ プラグインを構築するための vue カスタム命令の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Moment プラグインを使用して時間をフォーマットする vue のサンプルコード
  • vue+element を使用した Google プラグインの開発プロセス全体
  • スワイパープラグインを使用して Vue でカルーセルを実装する例
  • VueにExcelテーブルプラグインを導入する方法
  • Vue コード強調プラグインの総合的な比較と評価
  • vue-simple-uploader をベースに、ファイルセグメントアップロード、インスタントアップロード、ブレークポイント再開のグローバルアップロードプラグイン機能をカプセル化します。
  • vue-cli 3 で vue-bootstrap-datetimepicker 日付プラグインを使用する方法
  • Vue プラグイン エラー: このページで Vue.js が検出されました。問題は解決しました

<<:  MySQLは、where in()順序ソートを実装するためにfind_in_set()関数を使用します。

>>:  Docker を使用して Spring Boot をデプロイする方法の例

推薦する

jQueryはスライディングタブを実装する

この記事では、スライドタブを実装するためのjQueryの具体的なコードを参考までに紹介します。具体的...

JavaScriptを使用してSMS認証コード間隔を送信する機能を実装する

多くのアプリやウェブサイトでは、ログインやアカウント登録の際にSMS認証コード1を送信する場所があり...

mysql 8.0.18.zip のインストールと構成方法のグラフィック チュートリアル (Windows 64 ビット)

以前にインストールされたバージョンのデータベースをアンインストールする方法については、この記事を参照...

Nginxはリバースプロキシを使用して負荷分散プロセス分析を実装します

導入dockerコンテナとdocker-composeに基づいて、Linux環境でのdockerの基...

HTML で複数のフォームのテキスト ボックスを揃える方法

フォームのコードは図の通りです。スタイルシートがまだ追加されていないため、フォームが整列されておらず...

Vueはログイン認証コードを実装する

この記事では、ログイン認証コードを実装するためのvueの具体的なコードを例として紹介します。具体的な...

Linux で開いているポートへのリモート アクセスを許可する方法

1. ファイアウォール設定ファイルを変更する # vi /etc/sysconfig/iptable...

フロントエンドJavaScript ES6の詳細について

目次1. はじめに1.1 Babel トランスコーダ1.2 ポリフィル2. let と const ...

CSS ハック \9 と \0 は IE11\IE9\IE8 のハッキングには機能しない可能性があります

Web ページやフォームを設計するたびに、さまざまなブラウザ、特に IE ファミリの互換性の問題に悩...

JavaScript カラービューア

この記事では、カラービューアを実装するためのJavaScriptの具体的なコードを参考までに紹介しま...

JS で美しい条件式を書く方法についての簡単な説明

目次複数の条件文複数属性オブジェクトスイッチステートメントを置き換えるデフォルトパラメータとデストラ...

MySQL での utf8mb4 照合の例

MySQL における一般的な utf8mb4 ソート規則は次のとおりです。 utf8mb4_0900...

Linux ssh サービス情報と実行ステータスを表示する方法

Linux での ssh サービス構成など、ssh サーバー構成に関する記事は多数あります。ここでは...

Docker が占有するディスク領域をクリーンアップする方法

Docker は多くのスペースを占有します。コンテナを実行したり、イメージを取得したり、アプリケー...