vue.draggable的中文文档:https://www.itxst.com/vue-draggable/tutorial.html
代码段
<div style="overflow-y: auto;"> <draggable @sort="(event) => onDragEnd(event)" group="peo" :data-parent-id="0" v-model="scenes" > <template v-for="(scene,index) in scenes"> <div class="one-group" :class="!scene.children?'t_flex':''" :data-id="scene.id" :data-order="index"> <el-menu-item v-if="!scene.children" :index="`2-${scene.id}`" :key="scene.id" @click="getScene(scene)"><span>{{scene.title}}</span> <icon class="el-icon-plus add-group" @click="openMenu($event,scene)" @click.stop></icon> </el-menu-item> <template v-else> <item-cmp :menuitem="scene"/> </template> </div> </template> </draggable>
<script type="text/x-template" id="menu_item_cmp"> <draggable group="peo" :id="menuitem.id" @sort="(event) => onDragEnd(event)" v-model="menuitem.children" :data-parent-id="menuitem.id"> <template> <div class="two-group" v-for="(child,index) in menuitem.children" :data-id="child.id" :data-order="index" :key="child.id"> <el-menu-item v-if="!child.children" index="`3-${child.id}`" @click="getScene(child)"> <span v-html="child.title"></span> <icon class="el-icon-plus add-group" @click="openMenu($event, child)" @click.stop></icon> </el-menu-item> <template v-else> <item-cmp :menuitem="child"></item-cmp> </template> </div> </template> </draggable> </el-submenu> </script>
因为要实现菜单的无限级分类,所以这里使用的是组件递归的方法,我这里使用的是vue.js组件+内嵌组件的方法来实现。vue.draggable 的newindex 和orderindex 在多级菜单中使用会提供错误的排序值,所以我通过在对应节点上添加自定义数据属性。当排序发生改变时执行onDragEnd方法,group="peo"
:设置组名为 "peo",可以实现同名组件之间的拖拽。v-model="scenes"
:使用v-model绑定变量 scenes,识别需要拖拽的区域,这里将该区域数据绑定到 scenes 变量中。
需要注意的是以下几点:1.draggable最好要绑定v-model的值,因为v-model是用于实现数据的双向绑定,可以将dom元素和vue组件的数据状态同步,当排序改变时,排序的值会响应式更新。
2.因为采用的递归组件的方法,如果使用end事件来完成拖拽的话需要添加一个add事件,因为子组件的draggable如果拖到最外层不是触发的end事件而是add事件,所以我直接采用的sort事件来实现。
3.想清楚你要传递什么数据给服务器,如何来实现无限级分类的排序,在我的需求中,我只需要order,parent_id 和id这三个值就可以实现,所以我只需要想办法如何获取这3个的值就行了。如下所示: