其他分享
首页 > 其他分享> > vuedraggable 两个不同结构的数组之间拖拽

vuedraggable 两个不同结构的数组之间拖拽

作者:互联网

官方文档:

需求

最近做一个菜单收藏功能. 界面交互: 将没有收藏的菜单, 拖到已收藏的菜单中,
来实现收藏的功能.

需求:

  1. 能从未收藏区域, 拖动到已收藏的区域
  2. 未收藏的菜单区域, 不能拖动排序(顺序是排好的)
  3. 未收藏的菜单区域, 不能从已收藏的菜单中拖回来
  4. 已收藏的菜单, 点击删除后, 按原顺序回到未收藏的菜单中

使用的是 vuedraggable

数据结构如下:

+---------------------+              +---------------+
|    Collection       |              |       Menu    |
+---------------------+ 1          1 +---------------+
|-id:String           |--------------|-id:String     |
|-collectedTime:Date  | -menu        |-name:String   |
+---------------------+              +---------------+

实现

代码片段

模板:

<!-- 已收藏 -->
<el-row>
  <el-col :span='24'>
    <draggable
      :group='{name: "menu", put: true}'
      @add='addCollection'
      @update='sortCollection'
      :value="collections">
      <div v-for='collection in collections' :key='collection.id'>
        <collection-item
          @delete='deleteCollection'
          :deletable='modified'
          :collection='collection'></collection-item>
      </div>
    </draggable>
  </el-col>
</el-row>
<!-- 未收藏 -->
<el-row>
  <el-col :span='24'>
    <draggable
      :group='{name: "menu", put: false}'
      :sort='false'
      :value="notCollectedMenus">
      <div v-for='menu in notCollectedMenus' :key='menu.id'>
        <menu-item :menu='menu'></menu-item>
      </div>
    </draggable>
  </el-col>
</el-row>

js:

data: function () {
  return {
    collections: [],
    availableMenus: [],
  }
},
computed: {
  notCollectedMenus: function () {
    return this.availableMenus.filter(menu => {
      let collection = this.collections.find(collection => collection.menu.id === menu.id)
      return collection == undefined ? true : false
    })
  },
},
methods: {
  deleteCollection (collectionToBeDeleted) {
    let index = this.collections.findIndex(collection => collection.id == collectionToBeDeleted.id)
    this.collections.splice(index, 1)
  },
  addCollection (evt) {
    let newCollectionIndex = evt.newIndex
    let menuIndex = evt.oldIndex

    let menu = this.notCollectedMenus[menuIndex]
    let newCollection = {}
    newCollection.menu = menu
    newCollection.username = this.username
    this.collections.splice(newCollectionIndex, 0, newCollection)
  },
  sortCollection (evt) {
    let newIndex = evt.newIndex
    let oldIndex = evt.oldIndex

    let collection = this.collections[oldIndex]
    this.collections.splice(oldIndex, 1)
    this.collections.splice(newIndex, 0, collection)
  },
}

实现说明

vuedraggable 中, 不能使用 v-model, 而使用 value 属性.
v-model 会在排序, 拖进, 拖出的时候, 修改数组的内容, 而两个数组是不同构的,
这样程序会出错的.

既然不能用 v-model 来自动操作数据, 所以对应的排序, 拖进, 拖出操作,
需要自己来写相应的事件处理.

  1. 能从未收藏区域, 拖动到已收藏的区域

    两个 draggable 节点中, group 的 name 是一样的, 这样就可以实现两个区域的相互拖拽.

  2. 未收藏的菜单区域, 不能拖动排序(顺序是排好的)

    未收藏的 draggable 节点中加上 :sort='false'

  3. 未收藏的菜单区域, 不能从已收藏的菜单中拖回来

    未收藏的 draggable 节点中, group 添加 put: false

  4. 已收藏的菜单, 点击删除后, 按原顺序回到未收藏的菜单中

    该需求没有拖出要求, 从 collections 数组中删除, 通过计算属性 notCollectedMenus
    来添加到下面的区域.

标签:菜单,menu,collection,收藏,collections,vuedraggable,数组,let,拖拽
来源: https://www.cnblogs.com/hsnotebook/p/10656002.html