Drag and Drop UI Components vue.js ライブラリ

Vue.jsでドラッグ&ドロップするなら「Vue.Draggable」がおすすめ

2019年5月16日

Vue.Draggableとは

Vue.Draggableは、Vue.js製のドラッグ&ドロップコンポートネントライブラリです。

現存するVue.js製のドラッグ&ドロップライブラリとしては、最大の人気を誇ります。
コンパイルを必要としないUMD用のJSファイルが用意されているので、jQueryからの切り替えも容易に行う事が可能です。
単純にドラッグ&ドロップの機能が欲しければ、このライブラリを選んでおけば問題無いはずです。

主な使用用途並び順を変更するのはもちろん、複数のエリアを移動することが可能です。
さらにスマホにも対応しており、タッチイベントによる移動も可能となっています。

 

【動画サイズ:87KB】

 

環境

この記事は、以下の管理人の検証環境にて記事にしています。

vue.js 2.5.8
Vue.Draggable 2.23.2

 

ライブラリの取得

ライブラリを取得するには、npm, yarn, CDNのどれか一つを使用します。

npm

npm i -S vuedraggable 

yarn

yarn add vuedraggable

CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/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' 

UMDで実装する場合

const draggable = window['vuedraggable'];

 

2.テンプレートを準備

<draggable>tagプロパティにulolのような外部要素タグを設定します。
囲まれた内部にドラッグするリスト要素を設置します。

<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.メソッドを設定

1で取得したdraggablecomponents プロパティに設定します。

リスト用の配列をitemsとして設定します。
配列の渡しは、data から直接渡しても良いですし、computed を使っても大丈夫です。

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.テンプレートを準備

ドラッグ移動が可能なエリアを2つ準備します。
2つのエリアにそれぞれ違うリストを設定し、それぞれのoptionsに、オブジェクト形式でgroupのプロパティを持たせ、二つのエリアで同じ値を持たせます。
これで2つエリアを自由に行き来させることができます。

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

 

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イベントを例に使って解説します。

 

onEnd関数を作成する

まずイベントを作成します。
onEndというイベントをmethodsに作成します。
onEndの第一引数を設定しておくと、ドラッグアイテムのイベント情報が格納されます。
これで、ドラッグ後にイベントを反応させられます。

methods: {
  onEnd: function(originalEvent){
    console.log(originalEvent);//originalEventは イベントを取得できる
  }
}

 

@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 &gt; 0){
        no =  Math.max.apply(null,self.items.concat().map(function(item){return item.no;})) +1;
        self.newNo = self.newNo &lt; 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のオプションを使う

 

リストの並び順をブラウザに保存する

WEBアプリなどでブラウザに並び順を保存したい時などは、下記の記事が参考になります。

「Vue.Draggable」の並び順をブラウザに保存する方法

 

ドラッグリストをフィルタリングする

特定の文字を含むリストを並べ替えたり、カテゴリー絞り込みをしたい時の参考記事を書きました!↓

Vue.Draggableでフィルタリングされたリストを使用する

 

さいごに

Vue.js製のドラッグ&ドロップコンポートネントライブラリでした。

管理人が実務で触った感触的には、ドラッグ&ドロップするならこのライブラリを選んでおけば問題ないと思います。
よっぽど特殊なことをやりたいなら、このライブラリをカスタマイズするよりも別のライブラリを使うのが無難だと思います。

そういう意味では、Vue.js製のドラッグ&ドロップ系ライブラリは結構種類が豊富です。

今後そういったライブラリをご紹介していければと思います。

 

おまけ

別のライブラリになってしまいますが、ツリー形式にドラッグ要素を配置できるものもあります。
これを使えばWordpressのメニュー的なのも作れそうですね。

「vue-draggable-nested-tree」でドラッグ要素をツリー形式で配置する

 

今日はこの辺でー

 

  • この記事を書いた人

カバノキ

印刷会社のWEB部隊に所属してます。 WEB制作に携わってから、もう時期10年になります。 普段の業務では、PHPをメインにサーバーサイドの言語を扱っています。 最近のお気に入りはJavascriptです。 Vue.jsを狂喜乱舞しながら、社内に布教中です。

-Drag and Drop, UI Components, vue.js, ライブラリ
-, , , ,