
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、前回は「Vueでポップアップする画像つきセレクトボックスをつくる」という記事をお届けしました。
個人的にVue
でガッツリとコードを書いたのが久しぶりだったのですが、やっぱりVue
は使いやすいのでまたひとつ何かを作りたくなってしまいました。
そして、思いついたのが今回テーマの・・・
Trello風のタスク管理
です。
Trello
とはタスク管理の有名サイトですが、タスクをドラッグ・アンド・ドロップで状態変更するのが特徴的です。
そこで
今回はこの「ドラッグ・アンド・ドロップで状態変更する」機能をVue
で作ってみたいと思います。
ぜひ皆さんのお役に立てると嬉しいです
「開発でTrelloを使ってる人も
多いんじゃないでしょうか」
開発環境: Sortable 1.10.1、Vue 2.6.11、Vue.Draggable 2.23.2、Lodash 4.17.15
この記事を見たらできること
Trello のようにタスクをドラッグ・アンド・ドロップで移動させる機能がつくれます。
ではやっていきましょう
HTMLをつくる
まずはHTML部分です。
<html>
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app" class="px-5">
<h1 class="my-4">タスク管理</h1>
<div class="row">
<!--
グループ化したデータをループ ・・・ ① -->
<div class="col-md-4" v-for="(statusItems,statusId) in items">
<!--
ステータス名を取得 ・・・ ② -->
<h4 v-text="getStatusName(statusId)"></h4>
<!--
Vue.Draggableのコンポーネント ・・・ ③ -->
<draggable class="list-group"
v-model="items[statusId]"
group="items-todo-list"
@change="onChange($event, statusId)">
<div class="list-group-item bg-light"
:key="i.id"
v-for="i in statusItems"
v-text="i.name"></div>
</draggable>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.10.1/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.23.2/vuedraggable.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<script>
new Vue({
// ここにVueコード
});
</script>
</body>
</html>
①グループ化したデータをループ
v-for
を使ってループする内容は次のようなステータス(1: 入荷、2: 検品、3: 出荷)でグループ化したものです。(データ加工は次の項目で紹介します)
{
1: [
{ id: 1, name: '商品名 - 1', statusId: 1 },
// 省略
],
2: [
{ id: 5, name: '商品名 - 5', statusId: 2 },
// 省略
],
3: [
{ id: 10, name: '商品名 - 10', statusId: 3 },
// 省略
]
}
②ステータス名を取得
該当するステータス名をVue
から取得します。
③Vue.Draggableのコンポーネント
今回Vue.js
とSortable.js
を連携させたVue.Draggable
を使いますが、このパッケージはとても便利で、「draggable」という名前の専用コンポーネントを用意してくれています。
そのため、<draggable> ... </draggable>
の中に<div></div>
タグをセットするだけでドラッグ・アンド・ドロップ機能が有効になります。
JavaScriptをつくる
続いて、メインのJavaScript
部分を作っていきましょう。
new Vue({
el: '#app',
data: {
items: {},
statuses: [ //
状態
{ id: 1, name: '入荷' },
{ id: 2, name: '検品' },
{ id: 3, name: '出荷' },
]
},
methods: {
getStatusName(statusId) {
//
statuses から該当する名前を取得する ・・・ ①
const status = _.find(this.statuses, {
id: parseInt(statusId)
});
return status.name;
},
onChange(e, statusId) { //
ドラッグ・アンド・ドロップで移動したとき ・・・ ②
if(e.added) {
console.log('追加情報:', statusId, e.added);
} else if(e.removed) {
console.log('削除情報:', statusId, e.removed);
}
}
},
mounted() {
//
テストデータの作成 ・・・ ③
let allItems = [];
const statusIds = _.map(this.statuses, 'id');
for(let i = 0 ; i < 25 ; i++) {
allItems.push({
id: i,
name: '商品名 - '+ i,
statusId: _.sample(statusIds) // ランダムに取得
});
}
this.items = _.groupBy(allItems, 'statusId');
}
});
では、こちらもひとつずつご紹介します。
①statuses から該当する名前を取得する
Lodash.js
を使って、statuses
の中から「該当するid
のname
」を返しています。
statuses: [
{ id: 1, name: '入荷' },
{ id: 2, name: '検品' },
{ id: 3, name: '出荷' },
]
なお、ここで重要なのがparseInt
の部分です。
なぜなら、id
の型は数値なので、もし文字列の場合は別のものと判断されるからです。
②ドラッグ・アンド・ドロップで移動したとき
Vue.Draggable
が用意しているchange
イベントです。
コードを見ていただくと分かるように、1回の移動でadded
とremoved
のそれぞれ2回実行されることになります。
③テストデータの作成
ここでは、まずstatuses
から全id
を取得します。
(今回の場合は1
, 2
, 3
)
statuses: [
{ id: 1, name: '入荷' },
{ id: 2, name: '検品' },
{ id: 3, name: '出荷' },
]
そして、そのstatusIds
からランダムにデータ取得しながら25件のテストデータを用意します。
そして、_.groupBy()
でstatusId
ごとにグループ化します。
(ここが「グループ化したデータをループ」で説明した部分です)
テストしてみる
では、実際にテストしてみましょう
「入荷」にある「商品 – 4」を、「検品」の3つ目に移動させてみます。
ドラッグ・アンド・ドロップすると・・・・
はい
思ったとおりに移動させることができました。
成功です
教材ソースコードをダウンロードする
今回実際に開発した教材ソースコードを以下からダウンロードできます。
Trello風のタスク管理をつくる※CDN
を使っているので展開したらすぐ実行できますよ
おわりに
ということでVue
を使った移動できるタスク管理機能を作ってみました。
今回の開発で特に思ったことは、「Vue.Draggableがほぼ全て管理してくれるので頑張る部分がほとんどない」でした。
こういった便利な機能をどう組み合わせるかが開発者としての「腕」に繋がってくると思います。(ただ、カスタマイズする必要がある場合は自前での実装も検討した方がいいかもしれません)
ぜひ皆さんも便利なプラグインを探してみてくださいね。
ではでは〜
「画像編集のときは、
幻ラジオ聞いてます」