zhangyong
2024-02-23 9bd345bcd04bd59700cbf397e1a2aeeee8797f55
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<script lang="ts" setup>
import { defineComponent, reactive, ref, onUnmounted, nextTick } from 'vue'
import { VXETable, VxeGridInstance, VxeGridProps } from 'vxe-table'
import Sortable from 'sortablejs'
const xGrid2 = ref({} as VxeGridInstance)
 
const meanNum = (list: any[], field: string) => {
  let count = 0
  list.forEach(item => {
    count += Number(item[field])
  })
  return count / list.length
}
 
const sumNum = (list: any[], field: string) => {
  let count = 0
  list.forEach(item => {
    count += Number(item[field])
  })
  return count
}
 
const gridOptions2 = reactive({
  border: true,
  showFooter: true,
  class: 'sortable-column-demo',
  columnConfig: {
    useKey: true
  },
  scrollX: {
    enabled: false
  },
  toolbarConfig: {
    custom: true
  },
  columns: [
    { field: 'name', title: 'Name', fixed: 'left', width: 300 },
    { field: 'nickname', title: 'Nickname' },
    { field: 'role', title: 'Role' },
    { field: 'sex', title: 'Sex' },
    { field: 'age', title: 'Age' },
    { field: 'date3', title: 'Date' },
    { field: 'address', title: 'Address', width: 200, fixed: 'right', showOverflow: true }
  ],
  data: [
    { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },
    { id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
    { id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
    { id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: 'Women', age: 23, address: 'Shenzhen' },
    { id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: 'Women', age: 30, address: 'Shanghai' }
  ],
  footerMethod ({ columns, data }) {
    return [
      columns.map((column, columnIndex) => {
        if (columnIndex === 0) {
          return '平均'
        }
        if (['age', 'sex'].includes(column.property)) {
          return meanNum(data, column.property)
        }
        return null
      }),
      columns.map((column, columnIndex) => {
        if (columnIndex === 0) {
          return '和值'
        }
        if (['age', 'sex'].includes(column.property)) {
          return sumNum(data, column.property)
        }
        return null
      })
    ]
  }
} as VxeGridProps)
 
let sortable2: any
 
const columnDrop2 = () => {
  const $grid = xGrid2.value
  sortable2 = Sortable.create($grid.$el.querySelector('.body--wrapper>.vxe-table--header .vxe-header--row'), {
    handle: '.vxe-header--column',
    onEnd: (sortableEvent) => {
      const targetThElem = sortableEvent.item
      const newIndex = sortableEvent.newIndex as number
      const oldIndex = sortableEvent.oldIndex as number
      const { fullColumn, tableColumn } = $grid.getTableColumn()
      const wrapperElem = targetThElem.parentNode as HTMLElement
      const newColumn = fullColumn[newIndex]
      if (newColumn.fixed) {
        // 错误的移动
        const oldThElem = wrapperElem.children[oldIndex] as HTMLElement
        if (newIndex > oldIndex) {
          wrapperElem.insertBefore(targetThElem, oldThElem)
        } else {
          wrapperElem.insertBefore(targetThElem, oldThElem ? oldThElem.nextElementSibling : oldThElem)
        }
        VXETable.modal.message({ content: '固定列不允许拖动!', status: 'error' })
        return
      }
      // 获取列索引 columnIndex > fullColumn
      const oldColumnIndex = $grid.getColumnIndex(tableColumn[oldIndex])
      const newColumnIndex = $grid.getColumnIndex(tableColumn[newIndex])
      // 移动到目标列
      const currRow = fullColumn.splice(oldColumnIndex, 1)[0]
      fullColumn.splice(newColumnIndex, 0, currRow)
      $grid.loadColumn(fullColumn)
    }
  })
}
 
let initTime: any
nextTick(() => {
  // 加载完成之后在绑定拖动事件
  initTime = setTimeout(() => {
    columnDrop2()
  }, 500)
})
 
onUnmounted(() => {
  clearTimeout(initTime)
  if (sortable2) {
    sortable2.destroy()
  }
})
 
 
</script>
 
<template>
  <vxe-grid ref="xGrid2" v-bind="gridOptions2"></vxe-grid>
</template>
 
<style scoped>
.sortable-column-demo .vxe-header--row .vxe-header--column.sortable-ghost,
.sortable-column-demo .vxe-header--row .vxe-header--column.sortable-chosen {
  background-color: #dfecfb;
}
.sortable-column-demo .vxe-header--row .vxe-header--column.col--fixed {
  cursor: no-drop;
}
</style>