zoukankan      html  css  js  c++  java
  • 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)
      },
    }
    
    • collections 为收藏的数组, 里面的对象为 Collection,
    • availableMenus 为所有可被收藏菜单的数组, 里面的对象为 Menu
    • notCollectedMenus 为一个计算值, 为没有被收藏菜单的数组, 里面的对象为 Menu

    实现说明

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

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

    • add 拖进
    • update 排序
    1. 能从未收藏区域, 拖动到已收藏的区域

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

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

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

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

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

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

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

  • 相关阅读:
    APP测试之找密码
    测试理论
    LR性能测试
    Linux 操作系统常用命令
    C#后台HttpWebRequest代码调用WebService
    Python3在Windows下安装虚拟环境
    oracle使用rownum进行分页查询
    oracle over结合row_number分区进行数据去重处理
    Oracle实现主键自动增长
    Asp.net WebApi调用
  • 原文地址:https://www.cnblogs.com/hsnotebook/p/10656002.html
Copyright © 2011-2022 走看看