zoukankan      html  css  js  c++  java
  • vue2.0 不引用第三方包的情况下实现嵌套对象的拖拽排序功能

    先上一张效果图,然后再上代码(由于只做效果,未做数据相关的处理:实际处理数据时不修改 dom 元素,只是利用 dom 元素传递数据,然后需改数据,靠数据驱动效果)

    <div :id="index+'_morning'" style="min-height: 20px;"  @drop='drop($event)' @dragover='allowDrop($event)'>
                                    <li style="padding:0 0 5px 0">
                                        <span class="type-icon time"></span>上午(morning)
                                    </li>
                                <template v-if="item.morning !== undefined">
                                    <template v-for="(itemSon,idIdx) in item.morning">
                                    <li class="item ui-sortable-handle" :id="index+'_morning_'+idIdx"  draggable='true' @dragstart='drag($event)'   @drop='drop($event)' @dragover='allowDrop($event)'>
                                    <span class="destination-name">
                                      <em class="ball ball-red">{{itemSon.node_sort}}</em>
                                      <a href="javascript:;" class="item-name">{{itemSon.name}}</a>
                                      <NodeSetMore @click="onEventPoi(itemSon)" :poi="itemSon" v-on:poiOperate="onPoiOperate"></NodeSetMore>
                                      <DisplayIcon :poi="itemSon"></DisplayIcon>
                                    </span>
                                    </li>
                                    </template>
                                </template>
                                </div>
            methods: {
                // 拖拽相关
                drag:function(event){
                    console.log('拖动事件', event)
                    this.dom = event.currentTarget
                },
                drop:function(event){
                    event.preventDefault();
                    // 组织事件的传播(防止冒泡,节点向节点容器冒泡,因为都监听了此事件)
                    event.cancelBubble = true;
                    console.log('源对比', event.target, event.currentTarget)
                    console.log('目标id', event.currentTarget.id)
                    // 为event.currentTarget(点击事件本身)
                    // 分割id  2_morning格式为容器;2_morning_0为容器下的节点:
                    const idPath = event.currentTarget.id.split('_');
                    if (idPath.length === 2) {
                        event.currentTarget.appendChild(this.dom);
                    } else if(idPath.length === 3) {
                        // 获取当前排序第几,然后插在这个元素之后
                        event.currentTarget.parentNode.appendChild(this.dom);
                        // 重新改变顺序data中的数组顺序
                        this.againSort()
                    } else {
                        console.log("暂不处理", event.target)
                    }
                    //// 数据处理阶段,如果是节点容器,直接插在最前面,如果是节点,则放在这个节点后面
                    // // 不改变dom节点,直接改变数据
                    // this.tripList['1']['morning'].splice(0, 1);
                    // this.againSort()
                },
                allowDrop:function(event){
                    event.preventDefault();
                    // 组织事件的传播
                    event.cancelBubble = true;
                }
    }

    主要关注点在于 event.target 和 event.currentTarget 的理解,一个是事件触发时点击的元素(如:span),一个是事件触发时点击绑定事件的元素(如:li @drop)

  • 相关阅读:
    关于SuperSocket启动失败
    ffmpeg 常用命令
    Url中有中文参数需要编码解码
    单例模式
    c# 文件夹重命名
    一个既有winform又有webapi 的例子
    数据库查询字段的结构和长度
    Jquery 展开收起
    ajax即时修改
    EFCore 迁移
  • 原文地址:https://www.cnblogs.com/liugx/p/9601827.html
Copyright © 2011-2022 走看看