目次
vue.js : 2.5.8
Vue.Draggable: 2.16.0
ドラッグアンドドロップを使用したい時、jQueryなら jQuery UIで楽々実装ができます。
対して、Vue.jsならどうしたら良いのでしょうか?
Vue.jsなら、「Vue.Draggable」がおすすめです!
「Vue.Draggable」は、View-Modelと同期してドラッグ・アンド・ドロップによる並べ替えを可能にするVueコンポーネントです。
「Sortable.js」をベースに作られています。
ハンドラーを設定したり、アニメーションを追加したりする場合はSortable.jsのオプションを使います。
https://github.com/SortableJS/Vue.Draggable
https://jsfiddle.net/dede89/sqssmhtz/
私は、コンポーネントとかやらずに(やるならPHPでやる)、HTMLにゴリっと書いてしまうので、それでも良い人向けの解説です。
以下のCDNを読み込みます。
<!-- CDNJS :: Vue (https://cdnjs.com/) --> <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script> <!-- CDNJS :: Sortable (https://cdnjs.com/) --> <script src="//cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js></script> <!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) --> <script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>
次に、ドラッグしたいリストを<draggable>で囲みます。
computedを使うと上手く動かないので注意です!
いつの間にか?最初から? computedが使えるようになってました。
これでフィルターが楽になりますね。
1 2 3 4 5 | <ul id="main"> <draggable v-modal="myList"> <li v-for="item, index in myList" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable></ul> |
draggableにmodel="array"を設定します。
このarrayは、computedでも良いし、dataでも大丈夫です。
フィルターなどを考えると、computedを使うのが基本だと思います。
vueは、こんな感じでOK
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | new Vue({ el: "#main", data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'}, {no:3, name:'リンゴ', categoryNo:'3'}, {no:4, name:'冷蔵庫', categoryNo:'4'}, {no:5, name:'きゅうり', categoryNo:'1'}, {no:6, name:'ハンバーグ', categoryNo:'2'}, {no:7, name:'バナナ', categoryNo:'3'}, {no:8, name:'PS4', categoryNo:'4'} ] }, computed: { myList: { get() { return this.items; }, set(value) { this.items = value; } } }}); |
基本設定は、これだけです。
簡単ですね!
二つのエリアをドラッグで移動できるようにする。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | new Vue({ el: "#main", data: { items:[ {no:1, name:'キャベツ', categoryNo:'1'}, {no:2, name:'ステーキ', categoryNo:'2'}, {no:3, name:'リンゴ', categoryNo:'3'}, {no:4, name:'冷蔵庫', categoryNo:'4'} ], items2:[ {no:5, name:'きゅうり', categoryNo:'1'}, {no:6, name:'ハンバーグ', categoryNo:'2'}, {no:7, name:'バナナ', categoryNo:'3'}, {no:8, name:'PS4', categoryNo:'4'} ] }, computed: { myList: { get() { return this.items; }, set(value) { this.items = value; } } myList2: { get() { return this.items2; }, set(value) { this.items2 = value; } } }}); |
draggableに optionsでgroupを設定する。
下記の例はgroupにITEMSを設定している。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | <div id="main"> <div id="box1"> <ul> <draggable v-modal="myList" :options="{group:'ITEMS'}"> <li v-for="item, index in myList" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </ul> </div> <div id="box2"> <ul> <draggable v-modal="myList2" :options="{group:'ITEMS'}"> <li v-for="item, index in myList2" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable> </ul> </div></div> |
ドラッグイベントは以下の種類があります。
start, add, remove, update, end, choose, sort, filter, clone
endイベントを例にソースを書きます。
<draggable>に@end="onEnd"を追記します。
1 2 3 4 5 | <ul> <draggable @end="onEnd"> <li v-for="item, index in items" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable></ul> |
次に、methodでonEnd関数を作成します。
1 2 3 | onEnd: function(originalEvent){ //originalEventは イベントを取得できる} |
・引数のevtはドラッグアイテムのイベント情報が格納されている。
これで、ドラッグ後にイベントを反応させられます。
ドラッグ中を取得するmoveだけは要注意!
書き方が微妙に違います。
1 2 3 4 5 | <ul> <draggable :move="checkMove"> <li v-for="item, index in items" :key="item.no">{{item.name}}-(No.{{item.no}})</li> </draggable></ul> |
1 2 3 4 5 6 | checkMove: function(evt, originalEvent){ // evt はドラッグ中のアイテムのイベント情報を取得できる // evt.draggedContextの中にドラッグ前のドラッグアイテムの情報が格納されている // evt.relatedContextの中にドラッグ後のドラッグアイテムの情報が格納されている // originalEventはドラッグ後のアイテムのイベント情報を取得できる} |
・引数のevtはドラッグアイテムのイベント情報が格納されている。
・引数のevt.draggedContextはドラッグ前のドラッグアイテムの情報が格納されている
・引数のevt.relatedContextはドラッグ後のドラッグアイテムの情報が格納されている
・引数のoriginalEventはドラッグ後のアイテムのイベント情報を格納されている。
特定のアイテムだけドラッグしたくない場合は、moveイベントに以下のフィルターを設定する。
1 2 3 4 | checkMove: function(evt, aft){ // リンゴだったらドラッグできない return (evt.draggedContext.element.name!=='リンゴ');} |
「Vue.Draggable」は、「Sortable.js」をベースに作られています。
それ故に、「Sortable.js」の機能を完全にサポートしています。
https://github.com/RubaXa/Sortable#options
ドラッグできるハンドラーを設定したり、アニメーションを追加したりする場合はSortable.jsのオプションを使います。
絞り込みをしたリストをドラッグした場合は、下記記事を参考にしてください。
いかがでしょうか?
今日はこの辺でー