はじめに
本記事は以下で投稿した記事の続きです。
https://qiita.com/khata0131/items/c7c887ff3ea405e2aa85
前記事では、カンバンのチケット登録処理を実装し、ボタンによるステータス移動も実装しました。
本記事ではステータス移動をドラッグアンドドロップで実施できるように改修を加えます。
1.Vue.Draggable
ドラッグアンドドロップの機能を実装するために、Vue.Draggableというコンポーネントライブラリを利用します。
参考:https://www.kabanoki.net/1712/
以下、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>
2. コンポーネントの作成
取得したVue.Draggableのライブラリを呼び出します。
const draggable = window['vuedraggable'];
使用しているVueインスタンスに、呼び出したライブラリからコンポーネントを作成します。
new Vue({
el: '#app',
components: {
'draggable': draggable,
},
3. ドラッグアンドドロップの適用
ドラッグアンドドロップを適用したいエリアの親タグに対して、draggablelコンポーネントを適用させます。
まず、同じストーリー・同じステータスでチケットの移動ができるように、以下のキャプチャの青枠部分に対して適用させます。
tdタグにコンポーネントを適用していますが、コンポーネントはデフォルトでdivタグになってしまうため、
明示的にtag属性にてtdを指定しています。
Vue.component('ticket-col-template', {
props: ['story', 'status', 'statusindex'],
template: '\
<td is="draggable" tag="td">\
<li is="ticket-template"\
v-for="(ticket,index) in status.list"\
v-bind:key="index"\
v-bind:story="story"\
v-bind:ticket="ticket"\
v-bind:tindex="index"\
v-bind:statusindex="statusindex"\
class="ticket-li">\
</li>\
</td>\
',
})
以下のように同じストーリー・同じステータス内ではドラッグアンドドロップによるチケットの移動が可能になりました。
しかし、別ストーリー・別ステータスへの移動は、まだできない状態です。
4. ドラッグアンドドロップのエリアのグループ化
draggableコンポーネントは、グループ属性を設定することでドラッグアンドドロップできるエリアを複数設定することができます。
そのため、チケットエリアのテンプレートであるticket-col-templateを同じグループに設定することで、
別ストーリー・別ステータスへのドラッグアンドドロップによるチケットの移動が可能になります。
今回はグループ名をticketsとして、group属性を設定します。
<td is="draggable" tag="td" group="tickets">
また、ストーリー(行)の入れ替えも実装したいため、
ストーリーを設定しているtrタグの親であるtbodyタグにも同様にdraggableの設定をします。
<tbody is="draggable" tag="tbody">
<tr v-for="(story,index) in table" v-bind:key="index">
チケットは同じグループに設定した、各ストーリー・各ステータスに対してドラッグアンドドロップによる移動が可能になり、
ストーリーもチケットの状態を保持したまま順序の入れ替えが可能になりました。
終わりに
今回はドラッグアンドドロップの機能を実装するにあたりライブラリから取得しましたが、
自分で一からコーディングするよりも圧倒的に早い時間で実装することができました。
また、既存のプログラムへの影響もほとんどなかったので、ライブラリの選び方も重要だと感じました。
ドラッグアンドドロップの実装により、SPAの強みを生かしたページ構成になりモチベーションが向上したので、
他の機能の実装も続けていきたいと思います。