紹介とデモ最近、ドラッグアンドドロップリストが必要になり、シンプルで使いやすい Vue ドラッグ可能コンポーネントを見つけました。アムウェイ Vue Smooth DnD は、smooth-dnd ライブラリをラップする、高速で軽量なドラッグ アンド ドロップ、ソート可能な Vue.js ライブラリです。 Vue Smooth DnD は主に インストール: コンポーネントの基本的な使用方法を示し、ドラッグ可能なリストを実装する簡単なデモです。 <テンプレート> <div> <div class="シンプルページ"> <コンテナ @drop="onDrop"> <ドラッグ可能な v-for="item in items" :key="item.id"> <div class="ドラッグ可能なアイテム"> {{item.data}} </div> </ドラッグ可能> </コンテナ> </div> </div> </テンプレート> <スクリプト> 「vue-smooth-dnd」から Container、Draggable をインポートします。 const applyDrag = (arr, dragResult) => { const { removedIndex, addedIndex, payload } = dragResult console.log(削除されたインデックス、追加されたインデックス、ペイロード) if (removedIndex === null && addedIndex === null) は arr を返します。 const 結果 = [...arr] itemToAdd = ペイロード if (削除されたインデックス !== null) { 追加する項目 = result.splice(削除されたインデックス、1)[0] } 追加されたインデックスが null の場合 結果.splice(追加されたインデックス、0、追加する項目) } 結果を返す } const generateItems = (count, 作成者) => { 定数結果 = [] (i = 0 とします; i < count; i++) { 結果.push(作成者(i)) } 結果を返す } エクスポートデフォルト{ 名前:「シンプル」 コンポーネント: { コンテナ、ドラッグ可能 }, データ() { 戻る { アイテム: generateItems(50, i => ({ id: i, data: "Draggable " + i })) }; }, メソッド: { onDrop(ドロップ結果) { this.items = applyDrag(this.items、dropResult); } } }; </スクリプト> <スタイル> .ドラッグ可能なアイテム{ 高さ: 50px; 行の高さ: 50px; テキスト配置: 中央; 表示: ブロック; 背景色: #fff; アウトライン: 0; 境界線: 1px実線 rgba(0, 0, 0, .125); 下マージン: 2px; 上マージン: 2px; カーソル: デフォルト; ユーザー選択: なし; } </スタイル> 効果 API: コンテナ財産
<コンテナ #他のプロパティを省略... :animation-duration="1000" # 要素を配置した後のアニメーション遅延 drag-class="card-ghost" ドロップクラス="カードゴーストドロップ" :ドロッププレースホルダー="{ className: 'drop-preview'、# プレースホルダー スタイル animationDuration: '1000'、# プレースホルダー アニメーション遅延 showOnTop: true # 他の要素の上に表示するかどうか。false に設定すると、他のドラッグ要素によって覆われます。}" > <!-- ドラッグ可能な要素 --> <ドラッグ可能>....</ドラッグ可能> </コンテナ> クラス対応スタイル .カードゴースト{ 遷移: 変換 0.18 秒のイーズ; 変換: rotateZ(35deg); 背景: 赤 !重要; } .カードゴーストドロップ{ 遷移: transform 1s cubic-bezier(0,1.43,.62,1.56); 変換: rotateZ(0deg); 背景: 緑 !重要; } .drop-preview { 境界線: 1px 破線 #abc; マージン: 5px; 背景: 黄色 !重要; } 実際の効果(私の優れたカラーマッチング) ライフサイクルドラッグのライフサイクルは、一連のコールバックとイベントによって記述および制御されます。次の例には、説明のために 3 つのコンテナーが含まれています (ドキュメントは翻訳されずに直接コピーされます。API の詳細な説明は後で確認できます)。 マウスコールコールバック/イベントパラメータ注記 下 o 最初のクリック 移動 o 初期ドラッグ | | get-child-payload() インデックス関数はペイロードを返す必要があります | | 3 x should-accept-drop() srcOptions、payload すべてのコンテナに対して実行されます | | 3 x ドラッグ開始ドラッグ結果がすべてのコンテナに対して発動される | | ドラッグして入力 ヴ コンテナ上をドラッグして移動 | | nx drag-leave ドラッグ可能なコンテナが離れると起動されます | nx drag-enter ドラッグ可能なものがコンテナに入ると発火します ヴ 上へドラッグ終了 should-animate-drop() srcOptions、payload ドロップされたコンテナに対して1回実行されます 3 x ドラッグ終了ドラッグ結果がすべてのコンテナに対して発火しました nx drop dropResult ドロップ可能なコンテナに対してのみ実行されます
ドラッグ結果: { payload, # ペイロードはドラッグされているオブジェクトとして理解できます isSource, # ドラッグされているのはコンテナー自体ですか willAcceptDrop, # ドロップできますか? } ドロップ結果: { addedIndex、# 配置する新しく追加された要素のインデックス、または要素がない場合は null removedIndex、# 削除する要素のインデックス、または要素がない場合は null payload, # ドラッグされた要素オブジェクト。getChildPayload で指定できます。droppedElement, # 配置された DOM 要素} コールバックコールバックは、ユーザーとの対話の前と最中に追加のロジックとチェックを提供します。
イベント
API: ドラッグ可能
コンテナと同じ 実際の戦闘シンプルなチームコラボレーションタスクマネージャーを実装します。 <テンプレート> <div class="カードシーン"> <コンテナ 方向="水平" @drop="onColumnDrop($event)" ドラッグハンドルセレクター=".column-drag-handle" > <Draggable v-for="taskColumnList 内の列" :key="column.name"> <div class="カードコンテナ"> <div class="カード列ヘッダー"> <span class="column-drag-handle">☰</span> {{列名}} </div> <コンテナ グループ名="col" @drop="(e) => onCardDrop(column.id, e)" :get-child-payload="getCardPayload(column.id)" ドラッグクラス="カードゴースト" ドロップクラス="カードゴーストドロップ" :drop-placeholder="ドロッププレースホルダーオプション" クラス="ドラッグ可能なコンテナ" > <Draggable v-for="task in column.list" :key="task.id"> <div class="タスクカード"> <div class="task-title">{{ タスク名 }}</div> <div class="task-priority" :style="{ background: priorityMap[task.priority].color }"> {{ priorityMap[task.priority].label }} </div> </div> </ドラッグ可能> </コンテナ> </div> </ドラッグ可能> </コンテナ> </div> </テンプレート> <スクリプト> 「vue-smooth-dnd」から Container、Draggable をインポートします。 const applyDrag = (arr, dragResult) => { const { removedIndex, addedIndex, payload } = dragResult console.log(削除されたインデックス、追加されたインデックス、ペイロード) if (removedIndex === null && addedIndex === null) は arr を返します。 const 結果 = [...arr] itemToAdd = ペイロード if (削除されたインデックス !== null) { 追加する項目 = result.splice(削除されたインデックス、1)[0] } 追加されたインデックスが null の場合 結果.splice(追加されたインデックス、0、追加する項目) } 結果を返す } 定数タスクリスト = [ { 名前: 'ホームページ', 優先度: 'P1'、 ステータス: 「開発中」、 id: 1, }, { 名前: 「フローチャート開発」 優先度: 'P3'、 ステータス: 「審査待ち」、 id: 2, }, { 名前: '統計グラフ表示'、 優先度: 'P0'、 ステータス: 「開発中」、 id: 3, }, { 名前:「ファイル管理」 優先度: 'P1'、 ステータス: 「開発中」、 id: 4, } ] const statusList = ['レビュー保留中'、'開発保留中'、'開発中'、'完了'] const taskColumnList = statusList.map((ステータス、インデックス) => { 戻る { 名前: ステータス、 リスト: taskList.filter(item => item.status === status), id: インデックス } }) 定数優先度マップ = { 'P0': { ラベル:「最高品質」、 色: '#ff5454', }, 'P1': { ラベル:「高品質」、 色: '#ff9a00', }, 'P2': { ラベル: '中'、 色: '#ffd139', }, 'P3': { ラベル: 'lower'、 色: '#1ac7b5', }, } エクスポートデフォルト{ 名前:「カード」 コンポーネント: {コンテナ、ドラッグ可能}, データ () { 戻る { タスク列リスト、 優先度マップ、 ドロッププレースホルダーオプション: { クラス名: 'ドロッププレビュー', アニメーション期間: '150', 上部に表示: true } } }, メソッド: { onColumnDrop (dropResult) { this.taskColumnList = applyDrag(this.taskColumnList、dropResult) }, onCardDrop (列ID、ドロップ結果) { let { removedIndex, addedIndex, payload } = dropResult if (削除されたインデックス !== null || 追加されたインデックス !== null) { 定数列 = taskColumnList.find(p => p.id === columnId) if (addedIndex !== null && payload) { // タスクステータスを更新 dropResult.payload = { ...ペイロード、 ステータス: 列名、 } } 列リスト = applyDrag(列リスト、dropResult) } }, getCardPayload (列ID) { インデックスを返す => this.taskColumnList.find(p => p.id === columnId).list[インデックス] }, } } </スクリプト> <スタイル> * { マージン: 0; パディング: 0; フォント ファミリ: 'Microsoft YaHei'、'PingFang SC'、'Helvetica Neue'、Helvetica、サンセリフ; 行の高さ: 1.45; 色: rgba(0,0,0,.65); } .カードシーン{ ユーザー選択: なし; ディスプレイ: フレックス; 高さ: 100%; マージン: 20px; } .カードコンテナ{ ディスプレイ: フレックス; flex-direction: 列; 幅: 260ピクセル; 最小幅: 260px; 境界線の半径: 12px; 背景色: #edeff2; 右マージン: 16px; 高さ: calc(100vh - 40px); } .カード列ヘッダー { ディスプレイ: フレックス; 高さ: 50px; マージン: 0 16px; アイテムの位置を中央揃えにします。 フレックス収縮: 0; フォントの太さ: 500; フォントサイズ: 16px; } .ドラッグ可能なコンテナ{ フレックス成長: 1; オーバーフロー:自動; } .列ドラッグハンドル{ カーソル: 移動; パディング: 5px; } .タスクカード{ マージン: 10px; 背景色: 白; パディング: 15px 10px; 境界線の半径: 8px; ボックスの影: 0 1px 2px 0 rgba(0, 0, 0, 0.12); カーソル: ポインタ; ディスプレイ: フレックス; コンテンツの両端揃え: スペースの間; } .タスクタイトル{ 色: #333333; フォントサイズ: 14px; } .タスク優先度{ 幅: 60ピクセル; 行の高さ: 20px; 境界線の半径: 12px; テキスト配置: 中央; 色: #fff; フォントサイズ: 12px; } .カードゴースト{ 遷移: 変換 0.18 秒のイーズ; 変換: rotateZ(5deg) } .カードゴーストドロップ{ 遷移: transform 0.18s イーズインアウト; 変換: rotateZ(0deg) } .drop-preview { 背景色: rgba(150, 150, 200, 0.1); 境界線: 1px 破線 #abc; マージン: 5px; } </スタイル> 効果 Vue のドラッグ可能なコンポーネントである Vue Smooth DnD の詳細な使用方法については、これで終わりです。Vue のドラッグ可能なコンポーネントに関するその他の関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Linuxでユーザーが所属するグループを変更する方法
>>: MySQL 5.6.37 (zip) ダウンロード インストール 構成 グラフィック チュートリアル
ラジオ ボタンや複数選択ボタンにスタイルを追加する方法や、ボタンを大きくする方法を尋ねる人を以前見か...
1. いつsetUpを実行するかvue3 ではメソッドを正常に使用できるようになったことは誰もが知っ...
境界範囲間のmysql間の範囲は両側の境界値を含む例: 3 から 7 までの id は、id >...
Busybox: 小さなコマンドが詰まったスイスアーミーナイフ。ステップ1: ディレクトリ構造を作成...
Nginx を設定する 3 つの方法最初の方法は、位置一致部分を直接置き換える。 2 番目の pro...
目次day.js を使用する理由モーメントデイ.js day.js がなければどうなるでしょうか? ...
CentOS 7.3のインストール手順を図解しました。具体的な内容は次のとおりです。この記事では、v...
1.コンテナ内の /etc/hosts、/etc/resolv.conf、/etc/hostname...
はじめに<br />私はフロントエンド分野でかなり長い間働いており、CSS分野でも長い間...
Mongodb には db.serverStatus() コマンドがあり、これを使用して Mongo...
目次1. はじめに2. 直接回復2.1 mysqldumpバックアップの完全リカバリ2.2 xtra...
目次1. インストール2. カプセル化に問題はない3. ファイルを作成する4. アドレス設定をリクエ...
Web ページを設計する過程で、デザイナーが間違いを犯すのは必然です。特に新人は、新しいアイデアを実...
序文Crond は Linux のスケジュール実行ツール (Windows のスケジュールされたタス...
インライン形式<colgroup>...</colgroup>属性名 属性値...