目次
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のオプションを使います。
絞り込みをしたリストをドラッグした場合は、下記記事を参考にしてください。
いかがでしょうか?
今日はこの辺でー