Vue.jsでドラッグアンドドロップを実装【Vue.Draggable】
Author: 水卜
Author: 水卜
Vue.jsでドラッグ&ドロップを実装したい時はVue.Draggable安定。
公式
https://github.com/SortableJS/Vue.Draggable
デモサイト
https://sortablejs.github.io/Vue.Draggable/#/simple
$ npm install vuedraggable
TypeScriptで普通に使おうとすると以下のようなエラーが出る。
JavaScriptの場合はやらなくてOK
Could not find a declaration file for module 'vuedraggable'. '/******/node_modules/vuedraggable/dist/vuedraggable.umd.min.js' implicitly has an 'any' type.
Try `npm install @types/vuedraggable` if it exists or add a new declaration (.d.ts) file containing `declare module 'vuedraggable';`
以下手順を実行することで解決。
d.ts
ファイルをsrc直下に作成。名前はなんでも良い。
$ touch types.d.ts
d.ts
ファイルに以下を記述。
declare module 'vuedraggable'
dataの配列をドラッグ&ドロップしたい場合、v-modelで渡すだけで良い。
<draggable v-model="myArray">
<div v-for="element in myArray" :key="element.id">
{{element.name}}
</div>
</draggable>
Vuexを絡めて使う場合は、computedにget()
/set()
を定義して、ドラッグ&ドロップの結果がStoreに反映されるようにする。
<draggable v-model='myList'>
computed: {
myList: {
get() {
return this.$store.state.myList
},
set(value) {
this.$store.commit('updateList', value)
}
}
}
Type Scriptを使うため、Vue Property DecoratorやVue Class Componentなどを用いて書く場合は以下のような感じ。
export default class YourComponent extends Vue {
get myList () {
return myModule.getAll()
}
set myList (items) {
items.forEach((item, index) => {
myModule.update(item)
})
}
}
setterの引数には、ドラッグ&ドロップで並び替えた後のリストが来る。
これを利用して、クラスにorderプロパティを持たせ、setterでindexを書き込むことで、並び順を保存しておくことができる。
export default class YourComponent extends Vue {
get myList () {
return myModule.getAll().sort((a, b) => a.order - b.order)
}
set myList (items) {
items.forEach((item, index) => {
item.order = index
myModule.update(item)
})
}
}
他にもアニメーションやネストなど色々できるので公式READMEは一読を推奨。