【Vue3】vue.draggable の中で vue.draggable を使う（elementやindexに別名をつけられる）

# Vue2からのマイグレーションで躓く

vue.draggableを[ドキュメント](https://github.com/SortableJS/vue.draggable.next)に記載があるとおりにマイグレーションしていくと、以下のようになる。

```vue
<!-- vue 2 version -->
<draggable v-model="myArray">
  <div v-for="element in myArray" :key="element.id">{{element.id}}. {{element.name}}</div>
</draggable>
```

```vue
<!-- vue 3 version -->
<draggable v-model="myArray" item-key="id">
  <template #item="{element}">
    <div>{{element.id}}. {{element.name}}</div>
  </template>
</draggable>
```

## **vue.draggableの中でvue.draggableを利用している場合はどうするんだろう？**

例えば2階層のオブジェクト配列があり、それぞれを並び替えられるようにしたい場合、Vue2で以下のようになる。

```javascript
// 2階層のオブジェクト配列
const myArray = [
  {
    id: 1,
    name: "parent1",
    childArray: [
      {
         id: 1,
         name: "child1",
      },
      {
         id: 2,
         name: "child2",
      }
    ] 
  },
  {
    id: 2,
    name: "parent2",
    childArray: [
      {
         id: 3,
         name: "child3",
      },
      {
         id: 4,
         name: "child4",
      }
    ] 
  },
]
```

```vue
<!-- vue 2 version -->
<draggable v-model="myArray">
  <div v-for="element in myArray" :key="element.id">
    <div>{{element.id}}. {{element.name}}</div>
    <draggable v-model="element.childArray">
      <div v-for="element2 in element.childArray" :key="element2.id">{{element2.name}}</div>
    </draggable>
  </div>
</draggable>
```

しかし、ここで問題になるのが、Vue3では**elementを別の名前にするとエラーになってしまう**こと。

```vue
<!-- vue 3 version -->
<draggable v-model="myArray" item-key="id">
  <template #item="{row}">
    <div>{{row.id}}. {{row.name}}</div>
  </template>
</draggable>

// TypeError: Cannot read properties of undefined (reading 'id')
```

ドキュメントだけを見るとここで詰んでしまい、子要素用のコンポーネントを別途作成することを考えなければならない気がするが、いちいち値を双方向に受け渡す必要が出てきてしまい、ちょっと面倒くさい。


### っていうか、ループ変数が必ずelementになるってひどくない？

`array`なら`row`とか、`peoples` なら `people` にして視認性を確保できないものか。


## マニュアルに書いていないけど別名をつけることができた

```vuejs
<!-- vue 3 version -->
<draggable v-model="myArray" item-key="id">
  <template #item="{element}">
    <div>
      <div>{{element.id}}. {{element.name}}</div>
      <draggable v-model="element.myArray" item-key="id">
        <template #item="{element: element2}">
          <div>{{element2.id}}. {{element2.name}}</div>
        </template>
      </draggable>
  </template>
</draggable>
```

`{element: 別名}` とすることで今まで通り利用できるようになった。
これは`index`にも利用可能で、`{element: row, index: idx1}` などといった設定が可能。
フォームだとID属性つけたり、`引数付きcomputed`でゴニョゴニョするのに`index`を利用することも多いので、ここも任意の変数にできないと困るので非常に助かる。

```vuejs
<!-- vue 3 version -->
<!-- 視認性アップ -->
<draggable v-model="myArray" item-key="id">
  <template #item="{element: parentRow, index: idx1}">
    <div>
      <div>{{ idx1 + 1 }}行目： {{parentRow.id}}. {{parentRow.name}}</div>
      <draggable v-model="parentRow.myArray" item-key="id">
        <template #item="{element: childRow, index: idx2}">
          <div>{{ idx1 + 1 }}行目の{{ idx2 + 1 }}個目： {{childRow.id}}. {{childRow.name}}</div>
        </template>
      </draggable>
  </template>
</draggable>
```

## 参考資料

この使い方は唯一、Issueにてこの方法を見つけることができた。
ちゃんとドキュメントに書いておいてほしい・・・vue.draggableのマイグレーションで躓いている人、多いと思うんだ・・・
https://github.com/SortableJS/vue.draggable.next/issues/165