忘れないように記録しとこ

Vue.jsでドラッグアンドドロップを実装するなら「Vue.Draggable」がおすすめ

環境

vue.js : 2.5.8
Vue.Draggable: 2.16.0

 

はじめに

ドラッグアンドドロップを使用したい時、jQueryなら jQuery UIで楽々実装ができます。
対して、Vue.jsならどうしたら良いのでしょうか?

Vue.jsなら、「Vue.Draggable」がおすすめです!

 

Vue.Draggable

 

 

「Vue.Draggable」は、View-Modelと同期してドラッグ・アンド・ドロップによる並べ替えを可能にするVueコンポーネントです。
Sortable.js」をベースに作られています。

 

ハンドラーを設定したり、アニメーションを追加したりする場合はSortable.jsのオプションを使います。

 

Vue.Draggableで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が使えるようになってました。
これでフィルターが楽になりますね。

HTML
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>

draggablemodel="array"を設定します。

このarrayは、computedでも良いし、dataでも大丈夫です。

フィルターなどを考えると、computedを使うのが基本だと思います。

 

vueは、こんな感じでOK

javascript
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;
      }
    }
  }
});

 

基本設定は、これだけです。

簡単ですね!

 

複数のエリアをドラッグで移動できるようにする

二つのエリアをドラッグで移動できるようにする。

 

■Vue

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;
      }
   }
  }
});

■HTML

draggableに optionsgroupを設定する。

下記の例はgroupITEMSを設定している。

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>

 

 

ドラッグイベント

ドラッグイベントは以下の種類があります。

startaddremoveupdateendchoosesortfilterclone

 

endイベントを例にソースを書きます。

<draggable>@end="onEnd"を追記します。

HTML
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>

 

次に、methodonEnd関数を作成します。

JavaScript
1
2
3
onEnd: function(originalEvent){
  //originalEventは イベントを取得できる
}

 

・引数のevtはドラッグアイテムのイベント情報が格納されている。
これで、ドラッグ後にイベントを反応させられます。

 

moveイベント

ドラッグ中を取得するmoveだけは要注意!
書き方が微妙に違います。

HTML
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>

 

JavaScript
1
2
3
4
5
6
checkMove: function(evt, originalEvent){
 // evt はドラッグ中のアイテムのイベント情報を取得できる
 // evt.draggedContextの中にドラッグ前のドラッグアイテムの情報が格納されている
 // evt.relatedContextの中にドラッグ後のドラッグアイテムの情報が格納されている
 // originalEventはドラッグ後のアイテムのイベント情報を取得できる
}

・引数のevtはドラッグアイテムのイベント情報が格納されている。
・引数のevt.draggedContextはドラッグ前のドラッグアイテムの情報が格納されている
・引数のevt.relatedContextはドラッグ後のドラッグアイテムの情報が格納されている
・引数のoriginalEventはドラッグ後のアイテムのイベント情報を格納されている。

 

moveイベントでドラッグしたくないアイテムをフィルターする

特定のアイテムだけドラッグしたくない場合は、moveイベントに以下のフィルターを設定する。

JavaScript
1
2
3
4
checkMove: function(evt, aft){
  // リンゴだったらドラッグできない
  return (evt.draggedContext.element.name!=='リンゴ');
}

 

 

Sortable.jsの特徴

 

「Vue.Draggable」は、「Sortable.js」をベースに作られています。

それ故に、「Sortable.js」の機能を完全にサポートしています。
https://github.com/RubaXa/Sortable#options

 

ドラッグできるハンドラーを設定したり、アニメーションを追加したりする場合はSortable.jsのオプションを使います。

 

Vue.DraggableでSortable.jsのオプションを使う

 

リストをフィルタリング

絞り込みをしたリストをドラッグした場合は、下記記事を参考にしてください。

 

 

いかがでしょうか?

今日はこの辺でー

この記事が気に入ったら
いいね ! しよう

Twitter で

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.

:)