官方文檔:
需求
最近做一個菜單收藏功能. 界面交互: 將沒有收藏的菜單, 拖到已收藏的菜單中,
來實現收藏的功能.
需求:
- 能從未收藏區域, 拖動到已收藏的區域
- 未收藏的菜單區域, 不能拖動排序(順序是排好的)
- 未收藏的菜單區域, 不能從已收藏的菜單中拖回來
- 已收藏的菜單, 點擊刪除后, 按原順序回到未收藏的菜單中
使用的是 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
排序
-
能從未收藏區域, 拖動到已收藏的區域
兩個
draggable
節點中, group 的 name 是一樣的, 這樣就可以實現兩個區域的相互拖拽. -
未收藏的菜單區域, 不能拖動排序(順序是排好的)
未收藏的
draggable
節點中加上:sort='false'
-
未收藏的菜單區域, 不能從已收藏的菜單中拖回來
未收藏的
draggable
節點中, group 添加put: false
-
已收藏的菜單, 點擊刪除后, 按原順序回到未收藏的菜單中
該需求沒有拖出要求, 從 collections 數組中刪除, 通過計算屬性 notCollectedMenus
來添加到下面的區域.