Ant design vue-如何实现复选框类型的拖拽

在ant design vue中实现拖拽换位的方法目前只有树状控件可以实现

但是有时候我们的需求可能是需要复选框实现拖拽,点击控制表头的显示与隐藏下面我直接给出一个例子,

这是官网给的拖拽例子

<template>
  <a-tree
    class="draggable-tree"
    :default-expanded-keys="expandedKeys"
    draggable
    :tree-data="gData"
    @dragenter="onDragEnter"
    @drop="onDrop"
  />
</template>

<script>
const x = 3;
const y = 2;
const z = 1;
const gData = [];

const generateData = (_level, _preKey, _tns) => {
  const preKey = _preKey || '0';
  const tns = _tns || gData;

  const children = [];
  for (let i = 0; i < x; i++) {
    const key = `${preKey}-${i}`;
    tns.push({ title: key, key });
    if (i < y) {
      children.push(key);
    }
  }
  if (_level < 0) {
    return tns;
  }
  const level = _level - 1;
  children.forEach((key, index) => {
    tns[index].children = [];
    return generateData(level, key, tns[index].children);
  });
};
generateData(z);
export default {
  data() {
    return {
      gData,
      expandedKeys: ['0-0', '0-0-0', '0-0-0-0'],
    };
  },
  methods: {
    onDragEnter(info) {
      console.log(info);
      // expandedKeys 需要受控时设置
      // this.expandedKeys = info.expandedKeys
    },
    onDrop(info) {
      console.log(info);
      const dropKey = info.node.eventKey;
      const dragKey = info.dragNode.eventKey;
      const dropPos = info.node.pos.split('-');
      const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
      const loop = (data, key, callback) => {
        data.forEach((item, index, arr) => {
          if (item.key === key) {
            return callback(item, index, arr);
          }
          if (item.children) {
            return loop(item.children, key, callback);
          }
        });
      };
      const data = [...this.gData];

      // Find dragObject
      let dragObj;
      loop(data, dragKey, (item, index, arr) => {
        arr.splice(index, 1);
        dragObj = item;
      });
      if (!info.dropToGap) {
        // Drop on the content
        loop(data, dropKey, item => {
          item.children = item.children || [];
          // where to insert 示例添加到尾部,可以是随意位置
          item.children.push(dragObj);
        });
      } else if (
        (info.node.children || []).length > 0 && // Has children
        info.node.expanded && // Is expanded
        dropPosition === 1 // On the bottom gap
      ) {
        loop(data, dropKey, item => {
          item.children = item.children || [];
          // where to insert 示例添加到尾部,可以是随意位置
          item.children.unshift(dragObj);
        });
      } else {
        let ar;
        let i;
        loop(data, dropKey, (item, index, arr) => {
          ar = arr;
          i = index;
        });
        if (dropPosition === -1) {
          ar.splice(i, 0, dragObj);
        } else {
          ar.splice(i + 1, 0, dragObj);
        }
      }
      this.gData = data;
    },
  },
};
</script>

这是我写给大家的例子

<template>
    <div class="card-container">
        <div class="defineList">
            <a-row>
                <a-col :span="24">
                    <a-dropdown v-if="data.length > 0" v-model="visible" :trigger="['click']" class="selectMenuCont" placement="bottomLeft">
                        <a class="ant-dropdown-link" @click="e => e.preventDefault()">
                            管理显示信息
                            <a-icon type="down" />
                        </a>
                        <a-menu slot="overlay">
                            <a-tree
                                class="paperCheck"
                                v-model="checkedColumn"
                                checkable
                                :tree-data="columns"
                                :default-expanded-keys="expandedKeys"
                                draggable
                                @dragenter="onDragEnter"
                                @drop="onDrop"
                            />
                            <a-menu-divider />
                            <a-menu-item>
                                <a-button @click="handleMenuClickAll_comm">{{ selectText }}</a-button>
                                <a-button @click="handleMenuClick_comm">确定</a-button>
                                <a-button @click="colseMenuClick">取消</a-button>
                            </a-menu-item>
                        </a-menu>
                    </a-dropdown>
                </a-col>
            </a-row>
            <div>
                <a-table bordered :loading="loading" ref="table" :columns="selectedColumns" :data-source="data" :pagination="false"> </a-table>
            </div>
        </div>
    </div>
</template>

<script>
const data = [];
for (let i = 0; i < 5; i++) {
    data.push({
        key: i,
        uuid: `小灰灰`,
        name: `平底锅`,
        code: `2010-01-06`,
        sortNum: `¥16,340.20`,
        squarePerPage: `小白`,
        pathName: `水波`,
        psPath: `现金`,
        Path: `国家`
    });
}

export default {
    name: 'PaperPagedList',
    data() {
        return {
            columns: [],
            selectText: '全选',
            checkedColumn: [],
            selectedColumns: [],
            expandedKeys: [],
            loading: false,
            data,
            visible: false
        };
    },
    mounted() {
        this.columns = [
            {
                ellipsis: true,
                title: this.i18nRender('喜羊羊'),
                dataIndex: 'uuid',
                key: 'uuid'
            },
            {
                ellipsis: true,
                title: this.i18nRender('懒羊羊'),
                dataIndex: 'name',
                key: 'name'
            },
            {
                ellipsis: true,
                title: this.i18nRender('美羊羊'),
                dataIndex: 'code',
                key: 'code'
            },
            {
                ellipsis: true,
                title: this.i18nRender('沸羊羊'),
                dataIndex: 'sortNum',
                key: 'sortNum'
            },
            {
                ellipsis: true,
                title: this.i18nRender('慢羊羊'),
                dataIndex: 'squarePerPage',
                key: 'squarePerPage'
            },
            {
                ellipsis: true,
                title: this.i18nRender('暖羊羊'),
                dataIndex: 'pathName',
                key: 'pathName'
            },
            {
                ellipsis: true,
                title: this.i18nRender('灰太狼'),
                dataIndex: 'psPath',
                key: 'psPath'
            },
            {
                ellipsis: true,
                title: this.i18nRender('红太狼'),
                dataIndex: 'Path',
                key: 'Path'
            }
        ];
        this.selectedColumns = this.columns;
    },
    methods: {
        handleMenuClickAll_comm() {
            console.log(this.columns);
            if (this.checkedColumn.length === this.columns.length) {
                this.selectText = '全选';
                this.checkedColumn = [];
            } else if (this.checkedColumn.length > 0 && this.checkedColumn.length < this.columns.length) {
                if (this.selectText === '全选') {
                    this.checkedColumn = [];
                    this.columns.forEach(item => {
                        this.checkedColumn.push(item.key);
                    });
                    this.selectText = '全取消';
                } else {
                    this.checkedColumn = [];
                    this.selectText = '全选';
                }
            } else {
                this.selectText = '全取消';
                this.checkedColumn = [];
                this.columns.forEach(item => {
                    this.checkedColumn.push(item.key);
                });
            }
        },
        handleMenuClick_comm(e) {
            if (this.checkedColumn.length === 0) {
                this.$message.info('请至少勾选一项!');
                return;
            }
            this.visible = false;
            if (this.checkedColumn.length > 0) {
                let selectedColumns = this.columns.map(item => {
                    if (this.checkedColumn.indexOf(item.key) >= 0) {
                        item.isShow = '1';
                        return item;
                    } else {
                        return null;
                    }
                });
                this.selectedColumns = _.cloneDeep([...selectedColumns.filter(item => item !== null)]);
            }
        },
        colseMenuClick() {
            this.visible = false;
        },
        onDrop(info) {
            const dropKey = info.node.eventKey;
            const dragKey = info.dragNode.eventKey;
            const dropPos = info.node.pos.split('-');
            const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
            const loop = (data, key, callback) => {
                data.forEach((item, index, arr) => {
                    if (item.key === key) {
                        return callback(item, index, arr);
                    }
                    if (item.children) {
                        return loop(item.children, key, callback);
                    }
                });
            };
            const data = [...this.columns];

            // Find dragObject
            // 只在父级下进行拖拽
            let dragObj;
            loop(data, dragKey, (item, index, arr) => {
                arr.splice(index, 1);
                dragObj = item;
            });
            let ar;
            let i;
            loop(data, dropKey, (item, index, arr) => {
                ar = arr;
                i = index;
            });
            if (dropPosition === -1) {
                ar.splice(i, 0, dragObj);
            } else {
                ar.splice(i + 1, 0, dragObj);
            }
            this.columns = data;
        },
        onDragEnter(info) {
            console.log(info);
        }
    }
};
</script>
<style lang="less" scoped>
.selectMenuCont {
    float: right;
    margin-bottom: 41px;
    margin-right: 10px;
}
</style>

从代码上看我在官网的基础上进行了部分代码的删减,因为在前端要做到的是checkbox类型的复选和拖拽,又因为只有树有拖拽所以不不允许拖拽到父节点下,只能同级拖拽。
其次是只在点击确定下触发的事件。 !!!!切记data里一定不要漏掉声明

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容