へっぽこ社会人4年生がプログラミングを頑張る

へっぽこ社会人4年目がプログラミング系統を中心に書きたいことをつらつらと書きます

Vue.jsで要素をドラッグ&ドロップで手軽に動かす方法

Vue.jsでドラッグ&ドロップで要素を動かしたいなと思い、HTML5Drag and Drop APIの利用を考えましたが、移動元の要素の場所をドラッグ開始時(dragstart イベント)に保持して、ドロップ時(drop イベント)に要素を並び替える必要があり、少々実装が複雑です。もっと手軽な方法はないかと探してみると、 Vue.Draggable が見つかりました。

Vue.Draggableを利用すれば、Vue.jsで簡単に要素をドラッグ&ドロップで並び替えることができます。今回は、Vue.Draggableの手軽な使い方について書いていこうと思います。この記事では、Vue.jsのプロジェクトがvue-cliで作成済みであること、Single File Componentで利用することを前提とします。

Vue.Draggableのインストール

手順はVue.jsのプロジェクトに npmyarn 経由で vuedraggable をインストールするだけです。実行コマンドは次のようになります。

npm install vuedraggable -D

要素をドラッグ&ドロップで移動

ドラッグ&ドロップで並び替えたい要素のリストをVue.Draggableのコンポーネントのスロットに入れることで、簡単に要素を動かせるようになります。以降では、Vue.Draggableのコンポーネントdraggable として import します。

リスト内での移動

単一のリスト内で要素を並び替える際には、要素群を draggable のスロットに格納します。リストのデータを保持する配列を並び替え操作に反映させるためには、 draggablev-model ディレクティブに配列を与えます。

f:id:sierra-kilo:20191204214330g:plain

配列 flowers からなるリストについて、ドラッグ&ドロップで要素を動かすための実装例を示します。Vue.Draggableを使ってリストの要素を並び替えるコード例は以下の通りです。

<template>
  <ul>
    <draggable v-model="array">
      <li v-for="flower in flowers" :key="flower.id">{{ flower.name }}</li>
    </draggable>
  </ul>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: { draggable },
  data() {
    return {
      flowers: [
        { id: 1, name: 'Wisteria' },
        { id: 2, name: 'Dandelion' },
        { id: 3, name: 'Pansy' },
      ],
    };
  },
};
</script>

上記のコードは、 li 要素がドラッグ&ドロップで並び替えられます。また、 li のデータを格納する配列 flowersdraggable コンポーネントv-model ディレクティブに紐づけられているので、ドラッグ&ドロップで要素の場所が変わった際に、 flowers も自動的に要素が並び替えられます。

別のリストへの移動

Vue.Draggableを使えば、同一のリスト内で要素を動かすだけでなく、別のリストに要素を移動することも可能です。例えば、プロジェクト管理システムでタスクをTo DoのリストからDoingのリストに移すようなことが簡単に実装できます。

f:id:sierra-kilo:20191204215819g:plain

移動する要素を別のリストに移すためには、 group プロパティを利用します。同じ group として指定されていれば、別のリストにも要素をドラッグ&ドロップで移動できます。

ソースコード例は以下の通りです。

<template>
  <ul>
    <draggable v-model="todos" group="tasks">
      <li v-for="task in todos" :key="task.id">{{ task.title }}</li>
    </draggable>
  </ul>
  <ul>
    <draggable v-model="dones" group="tasks">
      <li v-for="task in dones" :key="task.id">{{ task.title }}</li>
    </draggable>
  </ul>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: { draggable },
  data() {
    return {
      todos: [
        { id: 1, title: 'Bake cake.' },
        { id: 2, title: 'Harvest raspberry' },
      ],
      dones: [
        { id: 3, title: 'Pour coffee' },
      ],
    };
  },
};
</script>

上記のプログラム例では、配列 todosdones の要素がそれぞれ同じ group に指定されています。同じ group として指定することで、 todos の要素を dones に、 dones の要素を todos に移動できます。

まとめ

Vue.Draggableを利用すれば、簡単に要素をドラッグ&ドロップで移動させることができます。1つのリスト内での移動だけでなく、別のリストに要素を移動させる処理も手軽に書くことができます。

Vue.Draggableは Sortable.js をベースに作られており、要素の移動時のイベント処理を記述することもできます。詳細は Vue.DraggableのGitHubリポジトリを参照してください。

参考文献