vue2+antd实现表格合并;excel效果

2 篇文章 0 订阅

效果图

在这里插入图片描述

一、html

<template>
  <div>
    <a-table :columns="columns" :dataSource="dataSource" rowKey="id" :pagination="false" bordered>
      
        <template slot="content1" slot-scope="text">
          {{text}}
        </template> </a-table>
  </div>
</template>

二、js

export default {

  data () {
   
    return {
      sortLevel: ['date'],
      columns: [
        {
          title: '日期',
          align: 'center',
          dataIndex: 'date',
          key: 'date',
          customRender: this.dateRender,

        },
        {
          title: '内容',
          colSpan: 2,
          dataIndex: 'content',
           scopedSlots: { customRender: 'content1' },
       
        },
        {
          title: '内容',
          colSpan: 0,
          dataIndex: 'content2',
          // customRender: renderContent,
        },
    
      ],
      datas: [
        {
          id: 1,
          content: '123',
          content2: 'qqw',
          date: '周一'

        },
        {
          id: 2,
          content: '123',
          content2: 'qwqw',

          date: '周二'

        },
        {
          id: 3,
          content: '123',
          content2: 'wewe',

          date: '周一'

        },
        ,
        {
          id: 42,
          content: '12332',
          content2: 'sad',

          date: '周三'

        },
        ,
        {
          id: 52,
          content: '1223',
          content2: 'asdasd',

          date: '周一'

        }
      ],
      dataSource: []
    }
  },
  mounted () {
    this.dataSource = this.convertData(this.datas)
    console.log('   this.dataSource : ', this.dataSource);
  },
  methods: {
    dateRender (value, row, index) {
      return {
        children: value,
        attrs: {
          rowSpan: row.dateRowSpan
        },
      };
    },
    // 获取需要合并数据的rowSpan
    convertData (arr, levelIndex = 0) {
      const levelKey = this.sortLevel
      const key = levelKey[levelIndex]

      // 根据不同维度重新整合数据
      let groupObj = this.groupBy(arr, key) || {};
      Object.keys(groupObj).forEach(groupKey => {
        if (levelIndex < levelKey.length - 1) {
          groupObj[groupKey] = this.convertData(groupObj[groupKey], levelIndex + 1)
        }
        // 计算rowSpan
        groupObj[groupKey].forEach((item, index, arr) => {
          item[`${key}RowSpan`] = index === 0 ? arr.length : 0
        })
      })

      return Object.values(groupObj).flat()
    },
    // 根据属性分组
    groupBy (arr = [], key) {
      let obj = {}
      arr.forEach(item => {
        const val = item[key]
        if (!obj[val]) {
          obj[val] = []
        }
        obj[val].push(item)
      })

      return obj
    },
  },
}

三、完整代码

<template>
  <div>
    <a-table :columns="columns" :dataSource="dataSource" rowKey="id" :pagination="false" bordered>
      </a-table>
  </div>
</template>

<script>


export default {

  data () {

    const renderContent = (value, row, index) => {
      const obj = {
        children: value,
        attrs: {},
      };
      if (index === 3) {
        obj.attrs.colSpan = 0;
      }
      return obj;
    };
    return {
      sortLevel: ['date'],
      columns: [
        {
          title: '日期',
          align: 'center',
          dataIndex: 'date',
          key: 'date',
          customRender: this.dateRender,

        },
        {
          title: '内容',
          colSpan: 2,
          dataIndex: 'content',
        
        },
        {
          title: '内容',
          colSpan: 0,
          dataIndex: 'content2',
          // customRender: renderContent,
        },
    
      ],
      datas: [
        {
          id: 1,
          content: '123',
          content2: 'qqw',
          date: '周一'

        },
        {
          id: 2,
          content: '123',
          content2: 'qwqw',

          date: '周二'

        },
        {
          id: 3,
          content: '123',
          content2: 'wewe',

          date: '周一'

        },
        ,
        {
          id: 42,
          content: '12332',
          content2: 'sad',

          date: '周三'

        },
        ,
        {
          id: 52,
          content: '1223',
          content2: 'asdasd',

          date: '周一'

        }
      ],
      dataSource: []
    }
  },
  mounted () {
    this.dataSource = this.convertData(this.datas)
    console.log('   this.dataSource : ', this.dataSource);
  },
  methods: {
    dateRender (value, row, index) {
      return {
        children: value,
        attrs: {
          rowSpan: row.dateRowSpan
        },
      };
    },
    // 获取需要合并数据的rowSpan
    convertData (arr, levelIndex = 0) {
      const levelKey = this.sortLevel
      const key = levelKey[levelIndex]

      // 根据不同维度重新整合数据
      let groupObj = this.groupBy(arr, key) || {};
      Object.keys(groupObj).forEach(groupKey => {
        if (levelIndex < levelKey.length - 1) {
          groupObj[groupKey] = this.convertData(groupObj[groupKey], levelIndex + 1)
        }
        // 计算rowSpan
        groupObj[groupKey].forEach((item, index, arr) => {
          item[`${key}RowSpan`] = index === 0 ? arr.length : 0
        })
      })

      return Object.values(groupObj).flat()
    },
    // 根据属性分组
    groupBy (arr = [], key) {
      let obj = {}
      arr.forEach(item => {
        const val = item[key]
        if (!obj[val]) {
          obj[val] = []
        }
        obj[val].push(item)
      })

      return obj
    },
  },
}
</script>
<style lang="less" scoped></style>```

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是一个完整的示例代码,基于Vue2,antd和sortablejs实现了两个表格之间的数据拖拽功能。 ```html <template> <div> <h2>表格1</h2> <a-table :columns="columns" :dataSource="list1" rowKey="id"> <template #name="{text, record}"> <span v-text="text" v-sortable="'table1'"></span> </template> </a-table> <h2>表格2</h2> <a-table :columns="columns" :dataSource="list2" rowKey="id"> <template #name="{text, record}"> <span v-text="text" v-sortable="'table2'"></span> </template> </a-table> </div> </template> <script> import Sortable from 'sortablejs' import { Table } from 'ant-design-vue' export default { components: { 'a-table': Table, }, data() { return { columns: [ { title: '姓名', dataIndex: 'name' }, { title: '年龄', dataIndex: 'age' }, ], list1: [ { id: 1, name: '张三', age: 18 }, { id: 2, name: '李四', age: 20 }, { id: 3, name: '王五', age: 22 }, ], list2: [], } }, mounted() { Sortable.create(this.$el.querySelector('.ant-table-tbody'), { group: { name: 'table1', put: ['table2'], }, animation: 150, fallbackOnBody: true, swapThreshold: 0.65, onEnd: this.onEnd, }) Sortable.create(this.$el.querySelectorAll('.ant-table-tbody')[1], { group: { name: 'table2', put: ['table1'], }, animation: 150, fallbackOnBody: true, swapThreshold: 0.65, onEnd: this.onEnd, }) }, methods: { onEnd(evt) { const { oldIndex, newIndex, item } = evt if (oldIndex !== newIndex) { const table = evt.to.dataset.table if (table === 'table1') { // 从表格1拖拽到表格2 this.list2.splice(newIndex, 0, this.list1.splice(oldIndex, 1)[0]) } else { // 从表格2拖拽到表格1 this.list1.splice(newIndex, 0, this.list2.splice(oldIndex, 1)[0]) } } }, }, } </script> ``` 在此示例中,我们使用Ant Design Vue中的`<a-table>`组件来渲染表格,并在模板中使用Vue的`v-sortable`指令来绑定Sortable实例。在mounted钩子函数中,我们为每个表格的tbody元素创建了Sortable实例,并将它们分组为“table1”和“table2”。然后,我们在onEnd方法中处理拖拽完成事件,并根据拖拽的方向和目标表格移动数据。 需要注意的是,在模板中,我们使用了`<span>`元素包装了表格中的文本数据,来实现拖拽时只能拖拽文本数据而不是整个行。同时,在Sortable实例的options中,我们设置了`fallbackOnBody`为true,这样拖拽元素在拖拽结束时会回到原来的位置,而不是消失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葫芦娃y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值