目次
Vue.Draggableとは
Vue.Draggableは、Vue.js製のドラッグ&ドロップコンポートネントライブラリです。
現存するVue.js製のドラッグ&ドロップライブラリとしては、最大の人気を誇ります。
コンパイルを必要としないUMD用のJSファイルが用意されているので、jQueryからの切り替えも容易に行う事が可能です。
単純にドラッグ&ドロップの機能が欲しければ、このライブラリを選んでおけば問題無いはずです。
主な使用用途の並び順を変更するのはもちろん、複数のエリアを移動することが可能です。
さらにスマホにも対応しており、タッチイベントによる移動も可能となっています。
【動画サイズ:87KB】
環境
この記事は、以下の管理人の検証環境にて記事にしています。
vue.js | 2.5.8 |
Vue.Draggable | 2.24.3 |
Vue3対応
Vue3を使用する場合は下記のURL
https://www.kabanoki.net/9532/
ライブラリの取得
ライブラリを取得するには、npm, yarn, CDNのどれか一つを使用します。
npm
npm i -S vuedraggable
yarn
yarn add vuedraggable
CDN
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.23.2/vuedraggable.umd.min.js"></script>
直接「Vue.Draggable」のリポジトリを取得する場合は、以下のURLから取得できます。
https://github.com/SortableJS/Vue.Draggable
導入手順
管理人が行った、動作確認サンプルを実装するために、以下の手順でソースコードを導入していきます。
このサンプルは、1つのエリアの中で並び順を変更するものになります。
1. ライブラリの呼び出し
まずライブラリを呼び出す為に、以下の2通りのケースで呼び出します。
ES6等で実装する場合
import draggable from 'vuedraggable'
CDNで実装する場合
const draggable = window['vuedraggable'];
2.テンプレートを準備
<draggable>
の内部がドラッグ可能なエリアになります。
tagプロパティへulやdivのような外部要素タグを設定します。
<draggable>
で囲まれた内部にドラッグするリスト要素を設置します。
サンプルでは、v-forを使ってループでリストを設定しています。
ポイント
ループに使う配列は、data から直接渡しても良いですし、computed を使っても大丈夫です。
<div id="app"> <draggable tag="ul"> <li v-for="item, index in items" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </div>
注意ポイント
リストのkeyプロパティを忘れずに設定しましょう!
これが無いと要素の追加・削除で、バグが多発するので必ず設定しましょう!
3.JavaScriptを設定
1で取得したdraggableを components
プロパティに設定します。
今回のサンプルはdateから直接ループに値を渡します。
リスト用の配列データitemsを設定します。
new Vue({ el: "#app", components: { 'draggable': draggable, }, data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'}, {no:3, name:'リンゴ', categoryNo:'3'} ] } });
4. リストにスタイルを適用する
Vue.DraggableにはjQuery uiのような専用のスタイルが無いので、見た目を整えるためにスタイルを自作する必要があります。
今回はサンプル用に下記のようなスタイルを適用します。
ul { list-style-type: none; } li { cursor: pointer; padding: 10px; border: solid #ddd 1px; }
サンプル
今回のソースを実際に触って確認できるようにデモを用意しました。
複数エリアの導入手順
次に上の1つのエリア内で並び順を変更するサンプルを参考にして、二つのエリアをドラッグ移動できるサンプルを実装するための導入を行ってみます。
以下の手順にしたがって、実装を行っていきます。
1.テンプレートを準備
ドラッグ移動が可能なエリアを用意する為に、<draggable>
を2つ準備します。
2つの<draggable>
エリアにoptionsで{group:'ITEMS'}
を持たせます。
これで2つ<draggable>
エリアを自由に行き来させることができます。
<div id="app"> <div id="box1" class="box"> <draggable tag="ul" :options="{group:'ITEMS'}"> <li v-for="item, index in items" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </div> <div id="box2" class="box"> <draggable tag="ul" :options="{group:'ITEMS'}"> <li v-for="item, index in items2" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </div> </div>
注意ポイント
エリア内のリストが空になると再ドラッグがし辛くなります。
<draggable>
に、スタイルでpadding:3px
みたいに厚みを持たせてあげるとドラッグがし易くなります。
2. 複数のdraggableリスト用に配列を用意する
2つのドラッグエリア用のリストをdataに用意します。
new Vue({ el: "#app", components: { 'draggable': draggable, }, data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'} ], items2:[ {no:5, name:'きゅうり', categoryNo:'1'}, {no:6, name:'ハンバーグ', categoryNo:'2'} ] } });
サンプル
今回のソースを実際に触って確認できるようにデモを用意しました。
イベント
ドラッグイベントは、任意のタイミングで動作します。
9種類のタイミングが用意されています。
イベント一覧
イベント | タイミング |
start | ドラッグ開始したとき |
add | 要素が追加されたとき |
remove | 要素を削除されたとき |
update | ドラッグで要素の移動が完了したとき |
end | ドラッグが完了したときの最後に動作します |
choose | ドラッグ要素を選択したとき |
sort | 並び順を変更したときのupdateの後、endの前に動作する |
filter | フィルターされたとき |
clone | ドラッグ時のシャドークローンが生成されたとき |
イベント導入例
今回はendイベントを例に使って解説します。
step.1 onEnd関数を作成する
まずイベントを作成します。
onEndというイベントをmethodsに作成します。
onEndの第一引数を設定しておくと、ドラッグアイテムのイベント情報が格納されます。
これで、ドラッグ後にイベントを反応させられます。
methods: { onEnd: function(originalEvent){ console.log(originalEvent);//originalEventは イベントを取得できる } }
step.2 @end="onEnd"をコンポーネントに設定する
上記で作成したonEndイベントを<draggable>
に設定します。
<ul> <draggable @end="onEnd"> <li v-for="item, index in items" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </ul>
リストに新規で追加する方法
あらかじめ用意されたリストに新規でドラッグ要素を追加したい場合は、以下が参考になります。
スクリプト
リストの配列にarray.push
を使って、新規のアイテムを追加します。
今回はdoAddというmedhodsを作成して、items配列にpush()
でオブジェクトを追加していきます。
new Vue({ el: "#app", data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'}, {no:3, name:'リンゴ', categoryNo:'3'} ], newNo: 4 }, computed: { myList: function(){ return this.items; } }, methods: { doAdd:function(){ var self = this; var no = 0; // itemsの中の一番大きなnoを取得して1を足す if(self.items.concat().length > 0){ no = Math.max.apply(null,self.items.concat().map(function(item){return item.no;})) +1; self.newNo = self.newNo < no ? no:self.newNo; } // itemsにアイテムを追加 this.items.push( { no: this.newNo, name:'追加リスト'+ this.newNo, categoryNo:'5' } ); }, } });
HTML
ボタンを用意して、クリックするとdoAddイベントが起動します。
<ul id="app"> <button v-on:click="doAdd">追加</button> <draggable> <li v-for="item, index in myList" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </ul>
サンプル
リストから削除する方法
リストの中からドラッグ要素を削除したい場合は、以下が参考になります。
スクリプト
リストの配列からarray.splice
を使って、アイテムを削除します。
doDeleteというmedhodsを作って、引数で配列のindexを受け取って、splice(index, 1)
で削除します。
new Vue({ el: "#app", data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'}, {no:3, name:'リンゴ', categoryNo:'3'} ] }, computed: { myList: function(){ return this.items; } }, methods: { doDelete: function(index){ this.items.splice(index, 1); }, } });
HTML
削除ボタンをクリックしてdoDeleteイベントを起動します。
引数にindexを持たせます。
<ul id="app"> <draggable> <li v-for="item, index in myList" :key="item.no"> {{item.name}}-(No.{{item.no}}) <span class="del" v-on:click="doDelete(index)">[削除]</span> </li> </draggable> </ul>
サンプル
ドラッグ時の掴める箇所やアニメーションを設定
Vue.Draggableは、Sortable.jsを元にしているので、同ライブラリのオプションを利用することができます。
例えば以下のようなオプションをしようすることができます。
カスタマイズできるモノ
- ドラッグアイテムの掴める箇所を指定する(ハンドラーを設定)
- ドラッグアイテムの移動時にアニメーションを設定する
- ドラッグ可能にするまでに時間を設定する
Sortable.jsのオプションを実装してみたい方は、以下の記事が参考になります。
-
-
Vue.DraggableでSortable.jsのオプションを使う
この記事は、「Vue.Draggable」でSortable.jsのオプションを使う方法を書いています。
リストの並び順をブラウザに保存する
WEBアプリなどでブラウザに並び順を保存したい時などは、下記の記事が参考になります。
-
-
「Vue.Draggable」の並び順をブラウザに保存する方法
以前から「Vue.Draggable」の並び順をブラウザに保存したいなあと思っていました。先日「vue-ls」というブラザストレージを操作するライブラリの記事を書いた際に、勢いで「Vue.Draggable」と組み合わせたシステムを作成しました。
ドラッグリストをフィルタリングする
特定の文字を含むリストを並べ替えたり、カテゴリーで絞り込みをしたい時の参考記事を書きました!↓
-
-
Vue.Draggableでフィルタリングされたリストを使用する
Vue.Draggableを使いながらリストをフィルタする機能が欲しいと思いました。
しかし、Vue.Draggableの特性と言いますか、制限のようなものでcomputedが使用できません。
そこで別のやり方で実装しました。
テーブルの列を並び替える
テーブルの列の順番を並び替える方法を記事にしました。
下記の記事を参考にしてください。
-
-
Vue.jsでテーブルの列移動を実装する
いつもの如くクライアントからデータ用テーブルの列を並び替えしたいとの要望がありました。
遥か昔の記憶で、Vue.Draggableを使ってサンプルを作った記憶があったので、引っ張り出してみました。せっかくなので、記事にしようと思います。
さいごに
Vue.js製のドラッグ&ドロップコンポートネントライブラリでした。
管理人が実務で触った感触的には、ドラッグ&ドロップするならこのライブラリを選んでおけば問題ないと思います。
よっぽど特殊なことをやりたいなら、このライブラリをカスタマイズするよりも別のライブラリを使うのが無難だと思います。
そういう意味では、Vue.js製のドラッグ&ドロップ系ライブラリは結構種類が豊富です。
今後そういったライブラリをご紹介していければと思います。
おまけ
別のライブラリになってしまいますが、ツリー形式にドラッグ要素を配置できるものもあります。
これを使えばWordpressのメニュー的なのも作れそうですね。
-
-
「vue-draggable-nested-tree」でドラッグ要素をツリー形式で配置する
vue-draggable-nested-treeは、ドラッグ要素をツリー形式に配置することが可能なdraggable&droppableコンポーネントです。tree-helper.js を使用することで、折りたたみを実装することも可能です。簡単に実装できるコピペと触って体感できるサンプルを掲載しています。
今日はこの辺でー