vxe-pc-ui 4.15.11 → 4.15.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/dist/all.esm.js +1597 -236
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/collapse/src/collapse.js +73 -40
  5. package/es/components.js +6 -0
  6. package/es/date-picker/src/date-picker.js +1 -0
  7. package/es/icon/style.css +1 -1
  8. package/es/image/src/image.js +14 -14
  9. package/es/language/ar-EG.js +4 -0
  10. package/es/language/de-DE.js +4 -0
  11. package/es/language/en-US.js +5 -1
  12. package/es/language/es-ES.js +4 -0
  13. package/es/language/fr-FR.js +4 -0
  14. package/es/language/hu-HU.js +4 -0
  15. package/es/language/hy-AM.js +4 -0
  16. package/es/language/id-ID.js +4 -0
  17. package/es/language/it-IT.js +4 -0
  18. package/es/language/ja-JP.js +4 -0
  19. package/es/language/ko-KR.js +4 -0
  20. package/es/language/ms-MY.js +4 -0
  21. package/es/language/nb-NO.js +4 -0
  22. package/es/language/pt-BR.js +4 -0
  23. package/es/language/ru-RU.js +4 -0
  24. package/es/language/th-TH.js +4 -0
  25. package/es/language/ug-CN.js +4 -0
  26. package/es/language/uk-UA.js +4 -0
  27. package/es/language/uz-UZ.js +4 -0
  28. package/es/language/vi-VN.js +4 -0
  29. package/es/language/zh-CHT.js +4 -0
  30. package/es/language/zh-CN.js +4 -0
  31. package/es/list/src/list.js +1163 -32
  32. package/es/list/src/store.js +8 -0
  33. package/es/list/style.css +328 -0
  34. package/es/list/style.min.css +1 -1
  35. package/es/print/src/util.js +1 -1
  36. package/es/pulldown/src/pulldown.js +4 -4
  37. package/es/style.css +1 -1
  38. package/es/style.min.css +1 -1
  39. package/es/table-transfer/index.js +12 -0
  40. package/es/table-transfer/src/table-transfer.js +65 -0
  41. package/es/table-transfer/style.css +0 -0
  42. package/es/table-transfer/style.min.css +0 -0
  43. package/es/transfer/index.js +12 -0
  44. package/es/transfer/src/transfer.js +91 -0
  45. package/es/transfer/style.css +4 -0
  46. package/es/transfer/style.min.css +1 -0
  47. package/es/tree/src/tree.js +20 -26
  48. package/es/tree/src/util.js +0 -7
  49. package/es/tree-select/src/tree-select.js +8 -7
  50. package/es/ui/index.js +14 -2
  51. package/es/ui/src/log.js +1 -1
  52. package/es/ui/src/utils.js +12 -0
  53. package/es/vxe-list/style.css +328 -0
  54. package/es/vxe-list/style.min.css +1 -1
  55. package/es/vxe-table-transfer/index.js +3 -0
  56. package/es/vxe-table-transfer/style.css +0 -0
  57. package/es/vxe-table-transfer/style.min.css +0 -0
  58. package/es/vxe-transfer/index.js +3 -0
  59. package/es/vxe-transfer/style.css +4 -0
  60. package/es/vxe-transfer/style.min.css +1 -0
  61. package/lib/collapse/src/collapse.js +89 -47
  62. package/lib/collapse/src/collapse.min.js +1 -1
  63. package/lib/components.js +25 -1
  64. package/lib/components.min.js +1 -1
  65. package/lib/date-picker/src/date-picker.js +1 -0
  66. package/lib/date-picker/src/date-picker.min.js +1 -1
  67. package/lib/icon/style/style.css +1 -1
  68. package/lib/icon/style/style.min.css +1 -1
  69. package/lib/image/src/image.js +17 -17
  70. package/lib/image/src/image.min.js +1 -1
  71. package/lib/index.umd.js +1753 -188
  72. package/lib/index.umd.min.js +1 -1
  73. package/lib/language/ar-EG.js +4 -0
  74. package/lib/language/ar-EG.min.js +1 -1
  75. package/lib/language/ar-EG.umd.js +4 -0
  76. package/lib/language/de-DE.js +4 -0
  77. package/lib/language/de-DE.min.js +1 -1
  78. package/lib/language/de-DE.umd.js +4 -0
  79. package/lib/language/en-US.js +5 -1
  80. package/lib/language/en-US.min.js +1 -1
  81. package/lib/language/en-US.umd.js +5 -1
  82. package/lib/language/es-ES.js +4 -0
  83. package/lib/language/es-ES.min.js +1 -1
  84. package/lib/language/es-ES.umd.js +4 -0
  85. package/lib/language/fr-FR.js +4 -0
  86. package/lib/language/fr-FR.min.js +1 -1
  87. package/lib/language/fr-FR.umd.js +4 -0
  88. package/lib/language/hu-HU.js +4 -0
  89. package/lib/language/hu-HU.min.js +1 -1
  90. package/lib/language/hu-HU.umd.js +4 -0
  91. package/lib/language/hy-AM.js +4 -0
  92. package/lib/language/hy-AM.min.js +1 -1
  93. package/lib/language/hy-AM.umd.js +4 -0
  94. package/lib/language/id-ID.js +4 -0
  95. package/lib/language/id-ID.min.js +1 -1
  96. package/lib/language/id-ID.umd.js +4 -0
  97. package/lib/language/it-IT.js +4 -0
  98. package/lib/language/it-IT.min.js +1 -1
  99. package/lib/language/it-IT.umd.js +4 -0
  100. package/lib/language/ja-JP.js +4 -0
  101. package/lib/language/ja-JP.min.js +1 -1
  102. package/lib/language/ja-JP.umd.js +4 -0
  103. package/lib/language/ko-KR.js +4 -0
  104. package/lib/language/ko-KR.min.js +1 -1
  105. package/lib/language/ko-KR.umd.js +4 -0
  106. package/lib/language/ms-MY.js +4 -0
  107. package/lib/language/ms-MY.min.js +1 -1
  108. package/lib/language/ms-MY.umd.js +4 -0
  109. package/lib/language/nb-NO.js +4 -0
  110. package/lib/language/nb-NO.min.js +1 -1
  111. package/lib/language/nb-NO.umd.js +4 -0
  112. package/lib/language/pt-BR.js +4 -0
  113. package/lib/language/pt-BR.min.js +1 -1
  114. package/lib/language/pt-BR.umd.js +4 -0
  115. package/lib/language/ru-RU.js +4 -0
  116. package/lib/language/ru-RU.min.js +1 -1
  117. package/lib/language/ru-RU.umd.js +4 -0
  118. package/lib/language/th-TH.js +4 -0
  119. package/lib/language/th-TH.min.js +1 -1
  120. package/lib/language/th-TH.umd.js +4 -0
  121. package/lib/language/ug-CN.js +4 -0
  122. package/lib/language/ug-CN.min.js +1 -1
  123. package/lib/language/ug-CN.umd.js +4 -0
  124. package/lib/language/uk-UA.js +4 -0
  125. package/lib/language/uk-UA.min.js +1 -1
  126. package/lib/language/uk-UA.umd.js +4 -0
  127. package/lib/language/uz-UZ.js +4 -0
  128. package/lib/language/uz-UZ.min.js +1 -1
  129. package/lib/language/uz-UZ.umd.js +4 -0
  130. package/lib/language/vi-VN.js +4 -0
  131. package/lib/language/vi-VN.min.js +1 -1
  132. package/lib/language/vi-VN.umd.js +4 -0
  133. package/lib/language/zh-CHT.js +4 -0
  134. package/lib/language/zh-CHT.min.js +1 -1
  135. package/lib/language/zh-CHT.umd.js +4 -0
  136. package/lib/language/zh-CN.js +4 -0
  137. package/lib/language/zh-CN.min.js +1 -1
  138. package/lib/language/zh-CN.umd.js +4 -0
  139. package/lib/list/src/list.js +1319 -30
  140. package/lib/list/src/list.min.js +1 -1
  141. package/lib/list/src/store.js +15 -0
  142. package/lib/list/src/store.min.js +1 -0
  143. package/lib/list/style/style.css +328 -0
  144. package/lib/list/style/style.min.css +1 -1
  145. package/lib/print/src/util.js +1 -1
  146. package/lib/print/src/util.min.js +1 -1
  147. package/lib/pulldown/src/pulldown.js +4 -0
  148. package/lib/pulldown/src/pulldown.min.js +1 -1
  149. package/lib/style.css +1 -1
  150. package/lib/style.min.css +1 -1
  151. package/lib/table-transfer/index.js +19 -0
  152. package/lib/table-transfer/index.min.js +1 -0
  153. package/lib/table-transfer/src/table-transfer.js +76 -0
  154. package/lib/table-transfer/src/table-transfer.min.js +1 -0
  155. package/lib/table-transfer/style/index.js +1 -0
  156. package/lib/table-transfer/style/style.css +0 -0
  157. package/lib/table-transfer/style/style.min.css +0 -0
  158. package/lib/transfer/index.js +19 -0
  159. package/lib/transfer/index.min.js +1 -0
  160. package/lib/transfer/src/transfer.js +95 -0
  161. package/lib/transfer/src/transfer.min.js +1 -0
  162. package/lib/transfer/style/index.js +1 -0
  163. package/lib/transfer/style/style.css +4 -0
  164. package/lib/transfer/style/style.min.css +1 -0
  165. package/lib/tree/src/tree.js +18 -24
  166. package/lib/tree/src/tree.min.js +1 -1
  167. package/lib/tree/src/util.js +0 -10
  168. package/lib/tree/src/util.min.js +1 -1
  169. package/lib/tree-select/src/tree-select.js +9 -6
  170. package/lib/tree-select/src/tree-select.min.js +1 -1
  171. package/lib/ui/index.js +14 -2
  172. package/lib/ui/index.min.js +1 -1
  173. package/lib/ui/src/log.js +1 -1
  174. package/lib/ui/src/log.min.js +1 -1
  175. package/lib/ui/src/utils.js +15 -0
  176. package/lib/ui/src/utils.min.js +1 -1
  177. package/lib/vxe-list/style/style.css +328 -0
  178. package/lib/vxe-list/style/style.min.css +1 -1
  179. package/lib/vxe-table-transfer/index.js +21 -0
  180. package/lib/vxe-table-transfer/index.min.js +1 -0
  181. package/lib/vxe-table-transfer/style/index.js +1 -0
  182. package/lib/vxe-table-transfer/style/style.css +0 -0
  183. package/lib/vxe-table-transfer/style/style.min.css +0 -0
  184. package/lib/vxe-transfer/index.js +21 -0
  185. package/lib/vxe-transfer/index.min.js +1 -0
  186. package/lib/vxe-transfer/style/index.js +1 -0
  187. package/lib/vxe-transfer/style/style.css +4 -0
  188. package/lib/vxe-transfer/style/style.min.css +1 -0
  189. package/package.json +1 -1
  190. package/packages/collapse/src/collapse.ts +81 -42
  191. package/packages/components.ts +6 -0
  192. package/packages/date-picker/src/date-picker.ts +1 -0
  193. package/packages/image/src/image.ts +14 -14
  194. package/packages/language/ar-EG.ts +4 -0
  195. package/packages/language/de-DE.ts +4 -0
  196. package/packages/language/en-US.ts +5 -1
  197. package/packages/language/es-ES.ts +4 -0
  198. package/packages/language/fr-FR.ts +4 -0
  199. package/packages/language/hu-HU.ts +4 -0
  200. package/packages/language/hy-AM.ts +4 -0
  201. package/packages/language/id-ID.ts +4 -0
  202. package/packages/language/it-IT.ts +4 -0
  203. package/packages/language/ja-JP.ts +4 -0
  204. package/packages/language/ko-KR.ts +4 -0
  205. package/packages/language/ms-MY.ts +4 -0
  206. package/packages/language/nb-NO.ts +4 -0
  207. package/packages/language/pt-BR.ts +4 -0
  208. package/packages/language/ru-RU.ts +4 -0
  209. package/packages/language/th-TH.ts +4 -0
  210. package/packages/language/ug-CN.ts +4 -0
  211. package/packages/language/uk-UA.ts +4 -0
  212. package/packages/language/uz-UZ.ts +4 -0
  213. package/packages/language/vi-VN.ts +4 -0
  214. package/packages/language/zh-CHT.ts +4 -0
  215. package/packages/language/zh-CN.ts +4 -0
  216. package/packages/list/src/list.ts +1276 -37
  217. package/packages/list/src/store.ts +14 -0
  218. package/packages/print/src/util.ts +1 -2
  219. package/packages/pulldown/src/pulldown.ts +4 -4
  220. package/packages/table-transfer/index.ts +16 -0
  221. package/packages/table-transfer/src/table-transfer.ts +91 -0
  222. package/packages/transfer/index.ts +16 -0
  223. package/packages/transfer/src/transfer.ts +117 -0
  224. package/packages/tree/src/tree.ts +20 -26
  225. package/packages/tree/src/util.ts +0 -10
  226. package/packages/tree-select/src/tree-select.ts +8 -7
  227. package/packages/ui/index.ts +14 -1
  228. package/packages/ui/src/utils.ts +15 -0
  229. package/styles/all.scss +2 -0
  230. package/styles/components/list.scss +245 -0
  231. package/styles/components/table-transfer.scss +0 -0
  232. package/styles/components/transfer.scss +4 -0
  233. package/styles/components/tree.scss +1 -0
  234. package/styles/theme/base.scss +3 -0
  235. package/styles/theme/dark.scss +10 -0
  236. package/styles/theme/light.scss +10 -0
  237. package/styles/variable.scss +11 -1
  238. package/types/all.d.ts +6 -0
  239. package/types/components/collapse.d.ts +4 -2
  240. package/types/components/list.d.ts +349 -17
  241. package/types/components/pulldown.d.ts +1 -0
  242. package/types/components/table-transfer.d.ts +84 -0
  243. package/types/components/table.d.ts +4 -0
  244. package/types/components/transfer.d.ts +84 -0
  245. package/types/components/tree-select.d.ts +4 -0
  246. package/types/components/tree.d.ts +1 -1
  247. package/types/ui/global-config.d.ts +4 -0
  248. package/types/ui/global-icon.d.ts +6 -1
  249. /package/es/icon/{iconfont.1782358507268.ttf → iconfont.1782658269305.ttf} +0 -0
  250. /package/es/icon/{iconfont.1782358507268.woff → iconfont.1782658269305.woff} +0 -0
  251. /package/es/icon/{iconfont.1782358507268.woff2 → iconfont.1782658269305.woff2} +0 -0
  252. /package/es/{iconfont.1782358507268.ttf → iconfont.1782658269305.ttf} +0 -0
  253. /package/es/{iconfont.1782358507268.woff → iconfont.1782658269305.woff} +0 -0
  254. /package/es/{iconfont.1782358507268.woff2 → iconfont.1782658269305.woff2} +0 -0
  255. /package/lib/icon/style/{iconfont.1782358507268.ttf → iconfont.1782658269305.ttf} +0 -0
  256. /package/lib/icon/style/{iconfont.1782358507268.woff → iconfont.1782658269305.woff} +0 -0
  257. /package/lib/icon/style/{iconfont.1782358507268.woff2 → iconfont.1782658269305.woff2} +0 -0
  258. /package/lib/{iconfont.1782358507268.ttf → iconfont.1782658269305.ttf} +0 -0
  259. /package/lib/{iconfont.1782358507268.woff → iconfont.1782658269305.woff} +0 -0
  260. /package/lib/{iconfont.1782358507268.woff2 → iconfont.1782658269305.woff2} +0 -0
@@ -1,21 +1,48 @@
1
- import { h, PropType, ref, Ref, computed, onBeforeUnmount, watch, reactive, nextTick, onActivated, onMounted } from 'vue'
1
+ import { h, PropType, ref, Ref, computed, onBeforeUnmount, watch, reactive, nextTick, onActivated, onMounted, VNode } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils from 'xe-utils'
4
- import { getConfig, globalEvents, globalResize, createEvent, useSize } from '../../ui'
5
- import { isScale } from '../../ui/src/dom'
4
+ import { getConfig, getIcon, getI18n, globalEvents, globalResize, createEvent, useSize, renderEmptyElement } from '../../ui'
5
+ import { getCrossListDragRowInfo } from './store'
6
+ import { isScale, removeClass, addClass, getTpImg, toCssUnit } from '../../ui/src/dom'
7
+ import { isEnableConf, getText, enModelValue, deModelValue } from '../../ui/src/utils'
8
+ import { createComponentLog } from '../../ui/src/log'
9
+ import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime'
6
10
  import VxeLoadingComponent from '../../loading/src/loading'
7
11
 
8
- import type { VxeListConstructor, VxeListPropTypes, VxeListEmits, ListReactData, ListInternalData, ValueOf, ListMethods, ListPrivateRef, VxeListMethods } from '../../../types'
12
+ import type { VxeListConstructor, VxeListPropTypes, VxeListEmits, ListReactData, ListInternalData, VxeListDefines, ValueOf, ListMethods, ListPrivateMethods, ListPrivateRef, VxeListMethods, VxeComponentStyleType } from '../../../types'
13
+
14
+ const { errLog } = createComponentLog('tree')
15
+
16
+ function getRowKeyByField (row: any, keyField: string) {
17
+ return row ? ('' + (row[keyField] || '')) : ''
18
+ }
19
+
20
+ function getRowIdByField (row: any, keyField: string) {
21
+ if (!row) {
22
+ return ''
23
+ }
24
+ const rowKey = getRowKeyByField(row, keyField)
25
+ return enModelValue(rowKey)
26
+ }
9
27
 
10
28
  function createReactData (): ListReactData {
11
29
  return {
12
30
  scrollYLoad: false,
13
31
  bodyHeight: 0,
32
+ headHeight: 0,
33
+ footHeight: 0,
14
34
  customHeight: 0,
15
35
  customMaxHeight: 0,
16
36
  parentHeight: 0,
17
37
  topSpaceHeight: 0,
18
- items: []
38
+ rowList: [],
39
+ selectRadioRow: null,
40
+ currRowFlag: 1,
41
+ updateCheckboxFlag: 1,
42
+ isAllChecked: false,
43
+ isAllIndeterminate: false,
44
+ dragRow: null,
45
+ dragTipText: ''
19
46
  }
20
47
  }
21
48
 
@@ -23,6 +50,7 @@ function createInternalData (): ListInternalData {
23
50
  return {
24
51
  resizeObserver: undefined,
25
52
  fullData: [],
53
+ fullKeyMaps: {},
26
54
  lastScrollLeft: 0,
27
55
  lastScrollTop: 0,
28
56
  scrollYStore: {
@@ -31,7 +59,11 @@ function createInternalData (): ListInternalData {
31
59
  visibleSize: 0,
32
60
  offsetSize: 0,
33
61
  rowHeight: 0
34
- }
62
+ },
63
+ currentRow: null,
64
+ selectCheckboxMaps: {}
65
+ // prevDragRow: null,
66
+ // prevDragPos: ''
35
67
  }
36
68
  }
37
69
 
@@ -52,11 +84,36 @@ export default defineVxeComponent({
52
84
  default: () => getConfig().list.autoResize
53
85
  },
54
86
  syncResize: [Boolean, String, Number] as PropType<VxeListPropTypes.SyncResize>,
87
+ showRadio: {
88
+ type: Boolean as PropType<VxeListPropTypes.ShowRadio>,
89
+ default: () => getConfig().list.showRadio
90
+ },
91
+ checkRowKey: [String, Number] as PropType<VxeListPropTypes.CheckRowKey>,
92
+ radioConfig: Object as PropType<VxeListPropTypes.RadioConfig>,
93
+ showCheckbox: {
94
+ type: Boolean as PropType<VxeListPropTypes.ShowCheckbox>,
95
+ default: () => getConfig().list.showCheckbox
96
+ },
97
+ checkRowKeys: Array as PropType<VxeListPropTypes.CheckRowKeys>,
98
+ checkboxConfig: Object as PropType<VxeListPropTypes.CheckboxConfig>,
99
+ rowConfig: Object as PropType<VxeListPropTypes.RowConfig>,
100
+ dragConfig: Object as PropType<VxeListPropTypes.DragConfig>,
55
101
  virtualYConfig: Object as PropType<VxeListPropTypes.VirtualYConfig>,
56
102
  scrollY: Object as PropType<VxeListPropTypes.ScrollY>
57
103
  },
58
104
  emits: [
59
- 'scroll'
105
+ 'update:checkRowKey',
106
+ 'update:checkRowKeys',
107
+ 'row-click',
108
+ 'row-dblclick',
109
+ 'current-change',
110
+ 'radio-change',
111
+ 'checkbox-change',
112
+ 'checkbox-all',
113
+ 'scroll',
114
+ 'row-dragstart',
115
+ 'row-dragover',
116
+ 'row-dragend'
60
117
  ] as VxeListEmits,
61
118
  setup (props, context) {
62
119
  const { slots, emit } = context
@@ -71,10 +128,17 @@ export default defineVxeComponent({
71
128
 
72
129
  const internalData = createInternalData()
73
130
 
131
+ const crossListDragRowInfo = getCrossListDragRowInfo()
132
+
74
133
  const refElem = ref() as Ref<HTMLDivElement>
134
+ const refHeaderElem = ref() as Ref<HTMLDivElement>
135
+ const refFooterElem = ref() as Ref<HTMLDivElement>
75
136
  const refVirtualWrapper = ref() as Ref<HTMLDivElement>
76
137
  const refVirtualBody = ref() as Ref<HTMLDivElement>
77
138
 
139
+ const refDragRowLineElem = ref<HTMLDivElement>()
140
+ const refDragTipElem = ref<HTMLDivElement>()
141
+
78
142
  const refMaps: ListPrivateRef = {
79
143
  refElem
80
144
  }
@@ -88,19 +152,62 @@ export default defineVxeComponent({
88
152
  getRefMaps: () => refMaps
89
153
  } as unknown as VxeListConstructor & VxeListMethods
90
154
 
155
+ const computeRowOpts = computed(() => {
156
+ return Object.assign({}, getConfig().list.rowConfig, props.rowConfig)
157
+ })
158
+
159
+ const computeDragOpts = computed(() => {
160
+ return Object.assign({}, getConfig().list.dragConfig, props.dragConfig)
161
+ })
162
+
91
163
  const computeSYOpts = computed(() => {
92
164
  return Object.assign({} as { gt: number }, getConfig().list.virtualYConfig || getConfig().list.scrollY, props.virtualYConfig || props.scrollY)
93
165
  })
94
166
 
95
- const computeStyles = computed(() => {
167
+ const computeKeyField = computed(() => {
168
+ const rowOpts = computeRowOpts.value
169
+ const { keyField } = rowOpts
170
+ return keyField || ''
171
+ })
172
+
173
+ const computeIsDrag = computed(() => {
174
+ const { dragConfig } = props
175
+ const dragOpts = computeDragOpts.value
176
+ return dragConfig && isEnableConf(dragOpts)
177
+ })
178
+
179
+ const computeRowHeight = computed(() => {
180
+ const rowOpts = computeRowOpts.value
181
+ const { height } = rowOpts
182
+ return height
183
+ })
184
+
185
+ const computeRadioOpts = computed(() => {
186
+ return Object.assign({ showIcon: true }, getConfig().list.radioConfig, props.radioConfig)
187
+ })
188
+
189
+ const computeCheckboxOpts = computed(() => {
190
+ return Object.assign({ showIcon: true }, getConfig().list.checkboxConfig, props.checkboxConfig)
191
+ })
192
+
193
+ const computeWrapperStyles = computed(() => {
194
+ const rowHeight = computeRowHeight.value
195
+ const style: VxeComponentStyleType = {}
196
+ if (rowHeight) {
197
+ style['--vxe-ui-list-row-height'] = toCssUnit(rowHeight)
198
+ }
199
+ return style
200
+ })
201
+
202
+ const computeVirtualStyles = computed(() => {
96
203
  const { height, maxHeight } = props
97
- const { customHeight, customMaxHeight } = reactData
98
- const style: { [key: string]: string | number } = {}
204
+ const { customHeight, customMaxHeight, headHeight, footHeight } = reactData
205
+ const style: VxeComponentStyleType = {}
99
206
  if (height) {
100
- style.height = `${customHeight}px`
207
+ style.height = toCssUnit(Math.max(20, customHeight - headHeight - footHeight))
101
208
  } else if (maxHeight) {
102
209
  style.height = 'auto'
103
- style.maxHeight = `${customMaxHeight}px`
210
+ style.maxHeight = toCssUnit(Math.max(20, customMaxHeight - headHeight - footHeight))
104
211
  }
105
212
  return style
106
213
  })
@@ -109,6 +216,19 @@ export default defineVxeComponent({
109
216
  emit(type, createEvent(evnt, { $list: $xeList }, params))
110
217
  }
111
218
 
219
+ const emitCheckboxMode = (value: VxeListPropTypes.CheckRowKeys) => {
220
+ emit('update:checkRowKeys', value)
221
+ }
222
+
223
+ const emitRadioMode = (value: VxeListPropTypes.CheckRowKey) => {
224
+ emit('update:checkRowKey', value)
225
+ }
226
+
227
+ const getRowId = (row: any) => {
228
+ const keyField = computeKeyField.value
229
+ return getRowIdByField(row, keyField)
230
+ }
231
+
112
232
  const calcTableHeight = (key: 'height' | 'maxHeight') => {
113
233
  const { parentHeight } = reactData
114
234
  const val = props[key]
@@ -129,6 +249,10 @@ export default defineVxeComponent({
129
249
  }
130
250
 
131
251
  const updateHeight = () => {
252
+ const headEl = refHeaderElem.value
253
+ const footEl = refFooterElem.value
254
+ reactData.headHeight = headEl ? Math.floor(headEl.offsetHeight) : 0
255
+ reactData.footHeight = footEl ? Math.floor(footEl.offsetHeight) : 0
132
256
  reactData.customHeight = calcTableHeight('height')
133
257
  reactData.customMaxHeight = calcTableHeight('maxHeight')
134
258
  }
@@ -143,7 +267,7 @@ export default defineVxeComponent({
143
267
  const handleData = () => {
144
268
  const { scrollYLoad } = reactData
145
269
  const { fullData, scrollYStore } = internalData
146
- reactData.items = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0)
270
+ reactData.rowList = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0)
147
271
  return nextTick()
148
272
  }
149
273
 
@@ -159,17 +283,17 @@ export default defineVxeComponent({
159
283
  const virtualBodyElem = refVirtualBody.value
160
284
  const sYOpts = computeSYOpts.value
161
285
  let rowHeight = 0
162
- let firstItemElem: HTMLElement | undefined
286
+ let firstRowElem: HTMLElement | undefined
163
287
  if (virtualBodyElem) {
164
288
  if (sYOpts.sItem) {
165
- firstItemElem = virtualBodyElem.querySelector(sYOpts.sItem) as HTMLElement
289
+ firstRowElem = virtualBodyElem.querySelector(sYOpts.sItem) as HTMLElement
166
290
  }
167
- if (!firstItemElem) {
168
- firstItemElem = virtualBodyElem.children[0] as HTMLElement
291
+ if (!firstRowElem) {
292
+ firstRowElem = virtualBodyElem.children[0] as HTMLElement
169
293
  }
170
294
  }
171
- if (firstItemElem) {
172
- rowHeight = firstItemElem.offsetHeight
295
+ if (firstRowElem) {
296
+ rowHeight = firstRowElem.offsetHeight
173
297
  }
174
298
  rowHeight = Math.max(12, rowHeight)
175
299
  scrollYStore.rowHeight = rowHeight
@@ -289,6 +413,46 @@ export default defineVxeComponent({
289
413
  dispatchEvent('scroll', { scrollLeft, scrollTop, isX, isY }, evnt)
290
414
  }
291
415
 
416
+ const updateRadioModeValue = () => {
417
+ const { checkRowKey } = props
418
+ const { fullKeyMaps } = internalData
419
+ if (checkRowKey) {
420
+ const row = fullKeyMaps[checkRowKey]
421
+ reactData.selectRadioRow = row || null
422
+ } else {
423
+ reactData.selectRadioRow = null
424
+ }
425
+ }
426
+
427
+ const updateCheckboxModeValue = () => {
428
+ const { checkRowKeys } = props
429
+ const { fullKeyMaps } = internalData
430
+ const keyField = computeKeyField.value
431
+ const selectMaps: Record<string, any> = {}
432
+ if (checkRowKeys && checkRowKeys.length) {
433
+ for (const rowKey of checkRowKeys) {
434
+ const row = fullKeyMaps[rowKey as string]
435
+ if (row) {
436
+ const rowid = getRowIdByField(row, keyField)
437
+ selectMaps[rowid] = row
438
+ }
439
+ }
440
+ }
441
+ internalData.selectCheckboxMaps = selectMaps
442
+ updateCheckboxStatus()
443
+ }
444
+
445
+ const cacheRowMap = () => {
446
+ const { fullData } = internalData
447
+ const keyField = computeKeyField.value
448
+ const keyMaps: Record<string, any> = {}
449
+ fullData.forEach(row => {
450
+ const rowKey = getRowKeyByField(row, keyField)
451
+ keyMaps[rowKey] = row
452
+ })
453
+ internalData.fullKeyMaps = keyMaps
454
+ }
455
+
292
456
  /**
293
457
  * 加载数据
294
458
  * @param {Array} datas 数据
@@ -305,12 +469,736 @@ export default defineVxeComponent({
305
469
  internalData.fullData = fullData
306
470
  // 如果gt为0,则总是启用
307
471
  reactData.scrollYLoad = !!sYOpts.enabled && sYOpts.gt > -1 && (sYOpts.gt === 0 || sYOpts.gt <= fullData.length)
472
+ cacheRowMap()
308
473
  handleData()
474
+ updateRadioModeValue()
475
+ updateCheckboxModeValue()
309
476
  return computeScrollLoad().then(() => {
310
477
  refreshScroll()
311
478
  })
312
479
  }
313
480
 
481
+ const clearRowDropOrigin = () => {
482
+ const el = refElem.value
483
+ if (el) {
484
+ const clss = 'row--drag-origin'
485
+ XEUtils.arrayEach(el.querySelectorAll(`.${clss}`), (elem) => {
486
+ (elem as HTMLTableCellElement).draggable = false
487
+ removeClass(elem, clss)
488
+ })
489
+ }
490
+ }
491
+
492
+ const updateRowDropOrigin = (row: any) => {
493
+ const sYOpts = computeSYOpts.value
494
+ const { sItem } = sYOpts
495
+ const el = refElem.value
496
+ if (el) {
497
+ const clss = 'row--drag-origin'
498
+ const rowid = getRowId(row)
499
+ XEUtils.arrayEach(el.querySelectorAll<HTMLDivElement>(`.vxe-list--row[rowid="${rowid}"]` + (sItem ? `${sItem}[rowid="${rowid}"]` : '')), (elem) => {
500
+ addClass(elem, clss)
501
+ })
502
+ }
503
+ }
504
+
505
+ const updateRowDropTipContent = (rowEl: HTMLElement) => {
506
+ const { dragRow } = reactData
507
+ const dragOpts = computeDragOpts.value
508
+ const { tooltipMethod } = dragOpts
509
+ const rTooltipMethod = tooltipMethod
510
+ let tipContent = ''
511
+ if (rTooltipMethod) {
512
+ const rtParams = {
513
+ $list: $xeList,
514
+ row: dragRow
515
+ }
516
+ tipContent = `${rTooltipMethod(rtParams) || ''}`
517
+ } else {
518
+ tipContent = getI18n('vxe.list.dragTip', [rowEl.textContent || ''])
519
+ }
520
+ reactData.dragTipText = tipContent
521
+ }
522
+
523
+ const hideDropTip = () => {
524
+ const rdTipEl = refDragTipElem.value
525
+ const rdLineEl = refDragRowLineElem.value
526
+ if (rdTipEl) {
527
+ rdTipEl.style.display = ''
528
+ }
529
+ if (rdLineEl) {
530
+ rdLineEl.style.display = ''
531
+ }
532
+ }
533
+
534
+ const clearCrossListDragStatus = () => {
535
+ // crossListDragRowObj = null
536
+ crossListDragRowInfo.row = null
537
+ }
538
+
539
+ const clearDragStatus = () => {
540
+ const { dragRow } = reactData
541
+ if (dragRow) {
542
+ hideDropTip()
543
+ clearRowDropOrigin()
544
+ clearCrossListDragStatus()
545
+ reactData.dragRow = null
546
+ }
547
+ }
548
+
549
+ const handleRowDragMousedownEvent = (evnt: MouseEvent, params: { row: any }) => {
550
+ evnt.stopPropagation()
551
+ const { row } = params
552
+ const dragConfig = computeDragOpts.value
553
+ const { trigger, dragStartMethod } = dragConfig
554
+ const dragEl = evnt.currentTarget as HTMLElement
555
+ const rowEl = trigger === 'row' ? dragEl : (dragEl.parentElement as HTMLElement).parentElement as HTMLElement
556
+ clearRowDropOrigin()
557
+ if (dragStartMethod && !dragStartMethod(params)) {
558
+ rowEl.draggable = false
559
+ reactData.dragRow = null
560
+ hideDropTip()
561
+ return
562
+ }
563
+ const dragstartEventParams: VxeListDefines.RowDragstartEventParams = {
564
+ row
565
+ }
566
+ reactData.dragRow = row
567
+ rowEl.draggable = true
568
+ updateRowDropOrigin(row)
569
+ updateRowDropTipContent(rowEl)
570
+ dispatchEvent('row-dragstart', dragstartEventParams, evnt)
571
+ }
572
+
573
+ const handleRowDragMouseupEvent = () => {
574
+ clearDragStatus()
575
+ }
576
+
577
+ const showDropTip = (evnt: DragEvent | MouseEvent, rowEl: HTMLElement | null, showLine: boolean, dragPos: string) => {
578
+ const wrapperEl = refElem.value
579
+ if (!wrapperEl) {
580
+ return
581
+ }
582
+ const wrapperRect = wrapperEl.getBoundingClientRect()
583
+ const wrapperHeight = wrapperEl.clientHeight
584
+ if (rowEl) {
585
+ const rdLineEl = refDragRowLineElem.value
586
+ if (rdLineEl) {
587
+ if (showLine) {
588
+ const trRect = rowEl.getBoundingClientRect()
589
+ let rowHeight = rowEl.clientHeight
590
+ const offsetTop = Math.max(1, trRect.y - wrapperRect.y)
591
+ if (offsetTop + rowHeight > wrapperHeight) {
592
+ rowHeight = wrapperHeight - offsetTop
593
+ }
594
+ rdLineEl.style.display = 'block'
595
+ rdLineEl.style.top = `${offsetTop}px`
596
+ rdLineEl.style.height = `${rowHeight}px`
597
+ rdLineEl.setAttribute('drag-pos', dragPos)
598
+ } else {
599
+ rdLineEl.style.display = ''
600
+ }
601
+ }
602
+ }
603
+ const rdTipEl = refDragTipElem.value
604
+ if (rdTipEl) {
605
+ rdTipEl.style.display = 'block'
606
+ rdTipEl.style.top = `${Math.min(wrapperEl.clientHeight - wrapperEl.scrollTop - rdTipEl.clientHeight, evnt.clientY - wrapperRect.y)}px`
607
+ rdTipEl.style.left = `${Math.min(wrapperEl.clientWidth - wrapperEl.scrollLeft - rdTipEl.clientWidth - 1, evnt.clientX - wrapperRect.x)}px`
608
+ rdTipEl.setAttribute('drag-status', showLine ? 'normal' : 'disabled')
609
+ }
610
+ }
611
+
612
+ const clearRowDragData = () => {
613
+ const wrapperEl = refElem.value
614
+ const dtClss = ['.vxe-list--row']
615
+ hideDropTip()
616
+ clearRowDropOrigin()
617
+ clearRowAnimate(wrapperEl, dtClss)
618
+ reactData.dragRow = null
619
+ }
620
+
621
+ const handleRowDragSwapEvent = (evnt: DragEvent | null, dragRow: any, prevDragRow: any, prevDragPos: '' | 'top' | 'bottom' | undefined) => {
622
+ const { fullData } = internalData
623
+ const dragConfig = computeDragOpts.value
624
+ const { animation, dragEndMethod } = dragConfig
625
+ const dEndMethod = dragEndMethod || (dragConfig ? dragConfig.dragEndMethod : null)
626
+ const dragOffsetIndex: 0 | 1 = prevDragPos === 'bottom' ? 1 : 0
627
+ const el = refElem.value
628
+ const errRest = {
629
+ status: false
630
+ }
631
+ if (!(el && prevDragRow && dragRow)) {
632
+ return Promise.resolve(errRest)
633
+ }
634
+ // 判断是否有拖动
635
+ if (prevDragRow !== dragRow) {
636
+ const dragParams = {
637
+ oldRow: dragRow,
638
+ newRow: prevDragRow,
639
+ dragRow,
640
+ dragPos: prevDragPos as 'top' | 'bottom',
641
+ offsetIndex: dragOffsetIndex
642
+ }
643
+
644
+ const dragRowid = getRowId(dragRow)
645
+ const _dragRowIndex = findRowIndexOfByKey(fullData, dragRowid)
646
+ const newRowid = getRowKey(prevDragRow)
647
+ let dragRowHeight = 0
648
+ let dragOffsetTop = -1
649
+ if (animation) {
650
+ const prevRowEl = el.querySelector<HTMLElement>(`.vxe-list--row[rowid="${newRowid}"]`)
651
+ const oldRowEl = el.querySelector<HTMLElement>(`.vxe-list--row[rowid="${dragRowid}"]`)
652
+ const targetRowEl = prevRowEl || oldRowEl
653
+ if (targetRowEl) {
654
+ dragRowHeight = targetRowEl.offsetHeight
655
+ }
656
+ if (oldRowEl) {
657
+ dragOffsetTop = oldRowEl.offsetTop
658
+ }
659
+ }
660
+
661
+ let oafIndex = -1
662
+ let nafIndex = -1
663
+
664
+ return Promise.resolve(dEndMethod ? dEndMethod(dragParams) : true).then((status) => {
665
+ if (!status) {
666
+ return errRest
667
+ }
668
+
669
+ // 移出
670
+ oafIndex = findRowIndexOf(fullData, dragRow)
671
+ fullData.splice(oafIndex, 1)
672
+ // 插入
673
+ const pafIndex = findRowIndexOf(fullData, prevDragRow)
674
+ nafIndex = pafIndex + dragOffsetIndex
675
+ fullData.splice(nafIndex, 0, dragRow)
676
+
677
+ handleData()
678
+ if (reactData.scrollYLoad) {
679
+ updateYSpace()
680
+ }
681
+
682
+ if (evnt) {
683
+ const dragendEventParams: VxeListDefines.RowDragendEventParams = {
684
+ oldRow: dragRow,
685
+ newRow: prevDragRow,
686
+ dragRow,
687
+ dragPos: prevDragPos as 'top' | 'bottom',
688
+ offsetIndex: dragOffsetIndex,
689
+ _index: {
690
+ newIndex: nafIndex,
691
+ oldIndex: oafIndex
692
+ }
693
+ }
694
+ dispatchEvent('row-dragend', dragendEventParams, evnt)
695
+ }
696
+
697
+ return nextTick().then(() => {
698
+ if (animation) {
699
+ const { rowList } = reactData
700
+ const { fullData } = internalData
701
+ const _newRowIndex = findRowIndexOfByKey(fullData, dragRowid)
702
+ const firstRow = fullData[0]
703
+ const _firstRowIndex = findRowIndexOf(fullData, firstRow)
704
+ const wrapperEl = el
705
+ if (_firstRowIndex > -1) {
706
+ const _lastRowIndex = _firstRowIndex + fullData.length
707
+
708
+ let rsIndex = -1
709
+ let reIndex = -1
710
+ let offsetRate = 1
711
+ if (_dragRowIndex < _firstRowIndex) {
712
+ // 从上往下虚拟拖拽
713
+ rsIndex = 0
714
+ reIndex = _newRowIndex - _firstRowIndex
715
+ } else if (_dragRowIndex > _lastRowIndex) {
716
+ // 从下往上虚拟拖拽
717
+ const $newRowIndex = findRowIndexOfByKey(rowList, dragRowid)
718
+ rsIndex = $newRowIndex + 1
719
+ reIndex = fullData.length
720
+ offsetRate = -1
721
+ } else {
722
+ if (_newRowIndex > _dragRowIndex) {
723
+ // 从上往下拖拽
724
+ rsIndex = _dragRowIndex - _firstRowIndex
725
+ reIndex = rsIndex + _newRowIndex - _dragRowIndex
726
+ } else {
727
+ // 从下往上拖拽
728
+ rsIndex = _newRowIndex - _firstRowIndex
729
+ reIndex = rsIndex + _dragRowIndex - _newRowIndex + 1
730
+ offsetRate = -1
731
+ }
732
+ }
733
+
734
+ const dragRangeList = fullData.slice(rsIndex, reIndex)
735
+ if (dragRangeList.length) {
736
+ const dtClss: string[] = []
737
+ dragRangeList.forEach(obj => {
738
+ const rowid = getRowId(obj)
739
+ dtClss.push(`.vxe-list--row[rowid="${rowid}"]`)
740
+ })
741
+ const dtTrList = wrapperEl.querySelectorAll<HTMLElement>(dtClss.join(','))
742
+ moveRowAnimateToTb(dtTrList, offsetRate * dragRowHeight)
743
+ }
744
+ }
745
+
746
+ const drClss = [`.vxe-list--row[rowid="${dragRowid}"]`]
747
+ const newDtTrList = wrapperEl.querySelectorAll<HTMLElement>(drClss.join(','))
748
+ const newTrEl = newDtTrList[0]
749
+ if (dragOffsetTop > -1 && newTrEl) {
750
+ moveRowAnimateToTb(newDtTrList, dragOffsetTop - newTrEl.offsetTop)
751
+ }
752
+ }
753
+
754
+ recalculate()
755
+ }).then(() => {
756
+ return {
757
+ status: true
758
+ }
759
+ })
760
+ }).catch(() => {
761
+ return errRest
762
+ }).then((rest) => {
763
+ clearRowDragData()
764
+ clearCrossListDragStatus()
765
+ return rest
766
+ })
767
+ }
768
+ clearRowDragData()
769
+ clearCrossListDragStatus()
770
+ return Promise.resolve(errRest)
771
+ }
772
+
773
+ const handleRowDragDragstartEvent = (evnt: DragEvent) => {
774
+ if (evnt.dataTransfer) {
775
+ evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
776
+ }
777
+ }
778
+
779
+ const handleRowDragDragendEvent = (evnt: DragEvent) => {
780
+ const { dragRow } = reactData
781
+ const { prevDragRow, prevDragPos } = internalData
782
+ handleRowDragSwapEvent(evnt, dragRow, prevDragRow, prevDragPos)
783
+ }
784
+
785
+ const handleRowDragDragoverEvent = (evnt: DragEvent) => {
786
+ const { dragRow } = reactData
787
+ const { fullData } = internalData
788
+ if (!dragRow) {
789
+ evnt.preventDefault()
790
+ }
791
+ const rowEl = evnt.currentTarget as HTMLElement
792
+ const rowid = rowEl.getAttribute('rowid') || ''
793
+ const row = findRowByKey(fullData, rowid)
794
+ if (row) {
795
+ evnt.preventDefault()
796
+ const offsetY = evnt.clientY - rowEl.getBoundingClientRect().y
797
+ const dragPos = offsetY < rowEl.clientHeight / 2 ? 'top' : 'bottom'
798
+ internalData.prevDragRow = row
799
+ internalData.prevDragPos = dragPos
800
+ if ((dragRow && getRowId(dragRow) === rowid)) {
801
+ showDropTip(evnt, rowEl, false, dragPos)
802
+ return
803
+ }
804
+ const dragOffsetIndex = dragPos === 'bottom' ? 1 : 0
805
+ const offsetIndex = dragOffsetIndex
806
+ const dragoverEventParams: VxeListDefines.RowDragoverEventParams = {
807
+ oldRow: dragRow,
808
+ targetRow: row,
809
+ dragPos,
810
+ dragRow,
811
+ offsetIndex
812
+ }
813
+ showDropTip(evnt, rowEl, true, dragPos)
814
+ dispatchEvent('row-dragover', dragoverEventParams, evnt)
815
+ }
816
+ }
817
+
818
+ const handleRowMousedownEvent = (evnt: MouseEvent, row: any) => {
819
+ const dragConfig = computeDragOpts.value
820
+ const isDrag = computeIsDrag.value
821
+ const { trigger, disabledMethod } = dragConfig
822
+ let isRowDrag = false
823
+ if (isDrag) {
824
+ isRowDrag = trigger === 'row'
825
+ }
826
+ const params = { row, $list: $xeList }
827
+ if (isRowDrag && !(disabledMethod && disabledMethod(params))) {
828
+ handleRowDragMousedownEvent(evnt, params)
829
+ }
830
+ }
831
+
832
+ const handleRowClickEvent = (evnt: MouseEvent, row: any) => {
833
+ const { currentRow } = internalData
834
+ const rowOpts = computeRowOpts.value
835
+ const { isCurrent } = rowOpts
836
+ let triggerCurrent = false
837
+ if (isCurrent) {
838
+ triggerCurrent = true
839
+ changeCurrentEvent(evnt, row)
840
+ } else if (currentRow) {
841
+ internalData.currentRow = null
842
+ reactData.currRowFlag++
843
+ }
844
+ dispatchEvent('row-click', { row, triggerCurrent }, evnt)
845
+ }
846
+
847
+ const handleRowDblclickEvent = (evnt: MouseEvent, row: any) => {
848
+ dispatchEvent('row-dblclick', { row }, evnt)
849
+ }
850
+
851
+ const getRowKey = (row: any) => {
852
+ const keyField = computeKeyField.value
853
+ return getRowKeyByField(row, keyField)
854
+ }
855
+
856
+ const eqRowKey = (rowKey1: any, rowKey2: string | number | null | undefined) => {
857
+ return ('' + rowKey1) === ('' + rowKey2)
858
+ }
859
+
860
+ const eqRow = (row1: any, row2: any) => {
861
+ if (row1 && row2) {
862
+ if (row1 === row2) {
863
+ return true
864
+ }
865
+ return eqRowKey(getRowId(row1), getRowId(row2))
866
+ }
867
+ return false
868
+ }
869
+
870
+ const eqRowByKey = (row: any, rowKey: any) => {
871
+ return row && eqRowKey(getRowKey(row), rowKey)
872
+ }
873
+
874
+ const findRow = (list: any, row: any) => {
875
+ return row ? XEUtils.find(list, obj => eqRow(obj, row)) : null
876
+ }
877
+
878
+ const findRowByKey = (list: any, rowKey: string | number | null | undefined) => {
879
+ const keyField = computeKeyField.value
880
+ return XEUtils.find(list, obj => eqRowKey(getRowIdByField(obj, keyField), rowKey))
881
+ }
882
+
883
+ const findRowIndexOf = (list: any, row: any) => {
884
+ return row ? XEUtils.findIndexOf(list, obj => eqRow(obj, row)) : -1
885
+ }
886
+
887
+ const findRowIndexOfByKey = (list: any, rowKey: string | number | null | undefined) => {
888
+ const keyField = computeKeyField.value
889
+ return XEUtils.findIndexOf(list, obj => eqRowKey(getRowIdByField(obj, keyField), rowKey))
890
+ }
891
+
892
+ const isCheckedByRadioRowKey = (rowKey: string | number | null | undefined) => {
893
+ const { selectRadioRow } = reactData
894
+ return getRowKey(selectRadioRow) === rowKey
895
+ }
896
+
897
+ const isCheckedByRadioRow = (row: any) => {
898
+ return isCheckedByRadioRowKey(getRowKey(row))
899
+ }
900
+
901
+ const isCheckedByCheckboxRowKey = (rowid: any) => {
902
+ const { updateCheckboxFlag } = reactData
903
+ const { selectCheckboxMaps } = internalData
904
+ return !!(updateCheckboxFlag && selectCheckboxMaps[rowid])
905
+ }
906
+
907
+ const isCheckedByCheckboxRow = (row: any) => {
908
+ return isCheckedByCheckboxRowKey(getRowKey(row))
909
+ }
910
+
911
+ const setCurrentRow = (row: any) => {
912
+ internalData.currentRow = row
913
+ reactData.currRowFlag++
914
+ return nextTick()
915
+ }
916
+
917
+ const setCurrentRowByKey = (rowKey: string | number | null | undefined) => {
918
+ const { fullData } = internalData
919
+ internalData.currentRow = findRowByKey(fullData, rowKey)
920
+ reactData.currRowFlag++
921
+ return nextTick()
922
+ }
923
+
924
+ const getCurrentRow = () => {
925
+ const { currentRow } = internalData
926
+ return currentRow
927
+ }
928
+
929
+ const getCurrentRowKey = () => {
930
+ const { currentRow } = internalData
931
+ return currentRow ? getRowKey(currentRow) : null
932
+ }
933
+
934
+ const clearCurrentRow = () => {
935
+ internalData.currentRow = null
936
+ reactData.currRowFlag++
937
+ return nextTick()
938
+ }
939
+
940
+ const setRadioRow = (row: any) => {
941
+ reactData.selectRadioRow = row
942
+ const value = getRowKey(row)
943
+ emitRadioMode(value)
944
+ return nextTick()
945
+ }
946
+
947
+ const setRadioRowByKey = (rowKey: string | number | null | undefined) => {
948
+ const { fullData } = internalData
949
+ reactData.selectRadioRow = findRowByKey(fullData, rowKey)
950
+ const value = rowKey as string
951
+ emitRadioMode(value)
952
+ return nextTick()
953
+ }
954
+
955
+ const getRadioRow = () => {
956
+ const { selectRadioRow } = reactData
957
+ return selectRadioRow
958
+ }
959
+
960
+ const getRadioRowKey = () => {
961
+ const { selectRadioRow } = reactData
962
+ return selectRadioRow ? getRowKey(selectRadioRow) : null
963
+ }
964
+
965
+ const clearRadioRow = () => {
966
+ const value = null
967
+ reactData.selectRadioRow = value
968
+ emitRadioMode(value)
969
+ return nextTick()
970
+ }
971
+
972
+ const setCheckboxRow = (row: any | any[], checked: boolean) => {
973
+ const { selectCheckboxMaps } = internalData
974
+ const keyField = computeKeyField.value
975
+ const rowList = row ? (XEUtils.isArray(row) ? row : [row]) : []
976
+ rowList.forEach(checked
977
+ ? (obj) => {
978
+ const rowid = getRowIdByField(obj, keyField)
979
+ if (!selectCheckboxMaps[rowid]) {
980
+ selectCheckboxMaps[rowid] = obj
981
+ }
982
+ }
983
+ : (obj) => {
984
+ const rowid = getRowIdByField(obj, keyField)
985
+ if (selectCheckboxMaps[rowid]) {
986
+ delete selectCheckboxMaps[rowid]
987
+ }
988
+ })
989
+ const value = getCheckboxRowKeys()
990
+ emitCheckboxMode(value)
991
+ return updateCheckboxStatus()
992
+ }
993
+
994
+ const setCheckboxRowByKey = (rowKey: string | number | null | undefined | (string | number | null | undefined)[], checked: boolean) => {
995
+ const { selectCheckboxMaps, fullKeyMaps } = internalData
996
+ const keyField = computeKeyField.value
997
+ const rowKeys = rowKey ? (XEUtils.isArray(rowKey) ? rowKey : [rowKey]) : []
998
+ rowKeys.forEach(checked
999
+ ? (key) => {
1000
+ const row = fullKeyMaps[key || '']
1001
+ if (row) {
1002
+ const rowid = getRowIdByField(row, keyField)
1003
+ if (row && !selectCheckboxMaps[rowid]) {
1004
+ selectCheckboxMaps[rowid] = row
1005
+ }
1006
+ }
1007
+ }
1008
+ : (key) => {
1009
+ const row = fullKeyMaps[key || '']
1010
+ if (row) {
1011
+ const rowid = getRowIdByField(row, keyField)
1012
+ if (selectCheckboxMaps[rowid]) {
1013
+ delete selectCheckboxMaps[rowid]
1014
+ }
1015
+ }
1016
+ })
1017
+ const value = getCheckboxRowKeys()
1018
+ emitCheckboxMode(value)
1019
+ return updateCheckboxStatus()
1020
+ }
1021
+
1022
+ const getCheckboxRows = () => {
1023
+ const { updateCheckboxFlag } = reactData
1024
+ const { selectCheckboxMaps } = internalData
1025
+ const rowList: string[] = []
1026
+ if (updateCheckboxFlag) {
1027
+ XEUtils.each(selectCheckboxMaps, row => {
1028
+ if (row) {
1029
+ rowList.push(row)
1030
+ }
1031
+ })
1032
+ }
1033
+ return rowList
1034
+ }
1035
+
1036
+ const getCheckboxRowKeys = () => {
1037
+ const { updateCheckboxFlag } = reactData
1038
+ const { selectCheckboxMaps } = internalData
1039
+ const keyField = computeKeyField.value
1040
+ const rowKeys: string[] = []
1041
+ if (updateCheckboxFlag) {
1042
+ XEUtils.each(selectCheckboxMaps, row => {
1043
+ if (row) {
1044
+ const rowKey = getRowKeyByField(row, keyField)
1045
+ rowKeys.push(rowKey)
1046
+ }
1047
+ })
1048
+ }
1049
+ return rowKeys
1050
+ }
1051
+
1052
+ const clearCheckboxRow = () => {
1053
+ internalData.selectCheckboxMaps = {}
1054
+ reactData.updateCheckboxFlag++
1055
+ reactData.isAllChecked = false
1056
+ reactData.isAllIndeterminate = false
1057
+ const value: string[] = []
1058
+ emitCheckboxMode(value)
1059
+ return nextTick()
1060
+ }
1061
+
1062
+ const setAllCheckboxRow = (checked: boolean) => {
1063
+ const { fullData, selectCheckboxMaps } = internalData
1064
+ const keyField = computeKeyField.value
1065
+ if (checked) {
1066
+ const value: string[] = []
1067
+ for (const row of fullData) {
1068
+ const rowKey = getRowKeyByField(row, keyField)
1069
+ const rowid = getRowIdByField(row, keyField)
1070
+ selectCheckboxMaps[rowid] = row
1071
+ value.push(rowKey)
1072
+ }
1073
+ emitCheckboxMode(value)
1074
+ return updateCheckboxStatus()
1075
+ }
1076
+ return clearCheckboxRow()
1077
+ }
1078
+
1079
+ const updateCheckboxStatus = () => {
1080
+ const { selectCheckboxMaps, fullData } = internalData
1081
+ const keyField = computeKeyField.value
1082
+ const checkboxOpts = computeCheckboxOpts.value
1083
+ const { checkMethod } = checkboxOpts
1084
+
1085
+ let hasChecked = false
1086
+ let hasUnchecked = false
1087
+ if (checkMethod) {
1088
+ for (const row of fullData) {
1089
+ if (checkMethod({ row, $list: $xeList })) {
1090
+ const rowid = getRowIdByField(row, keyField)
1091
+ if (selectCheckboxMaps[rowid]) {
1092
+ hasChecked = true
1093
+ } else {
1094
+ hasUnchecked = true
1095
+ if (hasChecked) {
1096
+ break
1097
+ }
1098
+ }
1099
+ }
1100
+ }
1101
+ } else {
1102
+ for (const row of fullData) {
1103
+ const rowid = getRowIdByField(row, keyField)
1104
+ if (selectCheckboxMaps[rowid]) {
1105
+ hasChecked = true
1106
+ } else {
1107
+ hasUnchecked = true
1108
+ if (hasChecked) {
1109
+ break
1110
+ }
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ reactData.isAllChecked = hasChecked && !hasUnchecked
1116
+ reactData.isAllIndeterminate = hasChecked && hasUnchecked
1117
+ reactData.updateCheckboxFlag++
1118
+ return nextTick()
1119
+ }
1120
+
1121
+ const changeCheckboxAllEvent = (evnt: MouseEvent) => {
1122
+ const { isAllChecked } = reactData
1123
+ const isChecked = !isAllChecked
1124
+ if (isChecked) {
1125
+ setAllCheckboxRow(true)
1126
+ } else {
1127
+ clearCheckboxRow()
1128
+ }
1129
+ dispatchEvent('checkbox-all', { checked: isChecked }, evnt)
1130
+ }
1131
+
1132
+ const changeCheckboxEvent = (evnt: MouseEvent, row: any) => {
1133
+ evnt.preventDefault()
1134
+ evnt.stopPropagation()
1135
+ const { selectCheckboxMaps } = internalData
1136
+ const checkboxOpts = computeCheckboxOpts.value
1137
+ const { checkMethod } = checkboxOpts
1138
+ const rowid = getRowId(row)
1139
+ const isDisabled = checkMethod ? !checkMethod({ $list: $xeList, row }) : false
1140
+ if (isDisabled) {
1141
+ return
1142
+ }
1143
+ let isChecked = false
1144
+ if (selectCheckboxMaps[rowid]) {
1145
+ delete selectCheckboxMaps[rowid]
1146
+ } else {
1147
+ isChecked = true
1148
+ selectCheckboxMaps[rowid] = row
1149
+ }
1150
+ reactData.updateCheckboxFlag++
1151
+ updateCheckboxStatus()
1152
+ const rowids = XEUtils.keys(selectCheckboxMaps)
1153
+ const value = rowids.map(deModelValue)
1154
+ emitCheckboxMode(value)
1155
+ dispatchEvent('checkbox-change', { row, value, checked: isChecked }, evnt)
1156
+ }
1157
+
1158
+ const changeCurrentEvent = (evnt: MouseEvent, row: any) => {
1159
+ evnt.preventDefault()
1160
+ const rowOpts = computeRowOpts.value
1161
+ const { currentMethod } = rowOpts
1162
+ let isDisabled = false
1163
+ if (currentMethod) {
1164
+ isDisabled = !currentMethod({ row })
1165
+ }
1166
+ if (isDisabled) {
1167
+ return
1168
+ }
1169
+ const isChecked = true
1170
+ internalData.currentRow = row
1171
+ reactData.currRowFlag++
1172
+ dispatchEvent('current-change', { row, checked: isChecked }, evnt)
1173
+ }
1174
+
1175
+ const changeRadioEvent = (evnt: MouseEvent, row: any) => {
1176
+ evnt.preventDefault()
1177
+ evnt.stopPropagation()
1178
+ const { selectRadioRow } = reactData
1179
+ const radioOpts = computeRadioOpts.value
1180
+ const { strict, checkMethod } = radioOpts
1181
+ const rowKey = getRowKey(row)
1182
+ const isDisabled = checkMethod ? !checkMethod({ $list: $xeList, row }) : false
1183
+ if (isDisabled) {
1184
+ return
1185
+ }
1186
+ const value = rowKey
1187
+ let isChecked = true
1188
+ if (strict) {
1189
+ if (selectRadioRow && rowKey === getRowKey(selectRadioRow)) {
1190
+ isChecked = false
1191
+ reactData.selectRadioRow = null
1192
+ } else {
1193
+ reactData.selectRadioRow = row
1194
+ }
1195
+ } else {
1196
+ reactData.selectRadioRow = row
1197
+ }
1198
+ emitRadioMode(value)
1199
+ dispatchEvent('radio-change', { row, value, checked: isChecked }, evnt)
1200
+ }
1201
+
314
1202
  const listMethods: ListMethods = {
315
1203
  dispatchEvent,
316
1204
  loadData,
@@ -322,31 +1210,328 @@ export default defineVxeComponent({
322
1210
  clearScroll()
323
1211
  return loadData(datas)
324
1212
  },
1213
+ getFullData () {
1214
+ const { fullData } = internalData
1215
+ return fullData
1216
+ },
325
1217
  recalculate,
326
1218
  scrollTo,
327
1219
  refreshScroll,
328
- clearScroll
1220
+ clearScroll,
1221
+ getRowKey,
1222
+ eqRowKey,
1223
+ eqRow,
1224
+ eqRowByKey,
1225
+ findRow,
1226
+ findRowByKey,
1227
+ findRowIndexOf,
1228
+ findRowIndexOfByKey,
1229
+ isCheckedByRadioRowKey,
1230
+ isCheckedByRadioRow,
1231
+ isCheckedByCheckboxRowKey,
1232
+ isCheckedByCheckboxRow,
1233
+ setCurrentRow,
1234
+ setCurrentRowByKey,
1235
+ getCurrentRow,
1236
+ getCurrentRowKey,
1237
+ clearCurrentRow,
1238
+ setRadioRow,
1239
+ setRadioRowByKey,
1240
+ getRadioRow,
1241
+ getRadioRowKey,
1242
+ clearRadioRow,
1243
+ setCheckboxRow,
1244
+ setCheckboxRowByKey,
1245
+ getCheckboxRows,
1246
+ getCheckboxRowKeys,
1247
+ clearCheckboxRow,
1248
+ setAllCheckboxRow
329
1249
  }
330
1250
 
331
- Object.assign($xeList, listMethods)
1251
+ const listPrivateMethods: ListPrivateMethods = {
1252
+ }
1253
+
1254
+ Object.assign($xeList, listMethods, listPrivateMethods)
1255
+
1256
+ const renderDragTip = () => {
1257
+ const { dragRow, dragTipText } = reactData
1258
+ const dragOpts = computeDragOpts.value
1259
+ const isDrag = computeIsDrag.value
1260
+ const dRow = dragRow
1261
+ if (isDrag) {
1262
+ return h('div', {
1263
+ class: 'vxe-list--drag-wrapper'
1264
+ }, [
1265
+ h('div', {
1266
+ ref: refDragRowLineElem,
1267
+ class: ['vxe-list--drag-row-line', {
1268
+ 'is--guides': dragOpts.showGuidesStatus
1269
+ }]
1270
+ }),
1271
+ dRow && dragOpts.showDragTip
1272
+ ? h('div', {
1273
+ ref: refDragTipElem,
1274
+ class: 'vxe-list--drag-sort-tip'
1275
+ }, [
1276
+ h('div', {
1277
+ class: 'vxe-list--drag-sort-tip-wrapper'
1278
+ }, [
1279
+ h('div', {
1280
+ class: 'vxe-list--drag-sort-tip-status'
1281
+ }, [
1282
+ h('span', {
1283
+ class: ['vxe-list--drag-sort-tip-normal-status', getIcon().LIST_DRAG_STATUS_NODE]
1284
+ }),
1285
+ h('span', {
1286
+ class: ['vxe-list--drag-sort-tip-disabled-status', getIcon().LIST_DRAG_DISABLED]
1287
+ })
1288
+ ]),
1289
+ h('div', {
1290
+ class: 'vxe-list--drag-sort-tip-content'
1291
+ }, dragTipText)
1292
+ ])
1293
+ ])
1294
+ : renderEmptyElement($xeList)
1295
+ ])
1296
+ }
1297
+ return renderEmptyElement($xeList)
1298
+ }
1299
+
1300
+ const renderRadio = (row: any, rowid: string, isChecked: boolean) => {
1301
+ const { showRadio } = props
1302
+ const radioOpts = computeRadioOpts.value
1303
+ const { showIcon, checkMethod, visibleMethod } = radioOpts
1304
+ const isVisible = !visibleMethod || visibleMethod({ $list: $xeList, row })
1305
+ if (showRadio && showIcon && isVisible) {
1306
+ const isDisabled = checkMethod ? !checkMethod({ $list: $xeList, row }) : false
1307
+ return h('div', {
1308
+ key: 'ct2',
1309
+ class: ['vxe-list--radio-option', {
1310
+ 'is--checked': isChecked,
1311
+ 'is--disabled': isDisabled
1312
+ }],
1313
+ onClick (evnt) {
1314
+ if (!isDisabled) {
1315
+ changeRadioEvent(evnt, row)
1316
+ }
1317
+ }
1318
+ }, [
1319
+ h('span', {
1320
+ class: ['vxe-radio--icon', isChecked ? getIcon().RADIO_CHECKED : getIcon().RADIO_UNCHECKED]
1321
+ })
1322
+ ])
1323
+ }
1324
+ return renderEmptyElement($xeList)
1325
+ }
1326
+
1327
+ const renderCheckbox = (row: any, rowid: string, isChecked: boolean) => {
1328
+ const { showCheckbox } = props
1329
+ const checkboxOpts = computeCheckboxOpts.value
1330
+ const { showIcon, checkMethod, visibleMethod } = checkboxOpts
1331
+ const isVisible = !visibleMethod || visibleMethod({ $list: $xeList, row })
1332
+ if (showCheckbox && showIcon && isVisible) {
1333
+ const isDisabled = checkMethod ? !checkMethod({ $list: $xeList, row }) : false
1334
+ return h('div', {
1335
+ key: 'ct3',
1336
+ class: ['vxe-list--checkbox-option', {
1337
+ 'is--checked': isChecked,
1338
+ 'is--disabled': isDisabled
1339
+ }],
1340
+ onClick (evnt) {
1341
+ if (!isDisabled) {
1342
+ changeCheckboxEvent(evnt, row)
1343
+ }
1344
+ }
1345
+ }, [
1346
+ h('span', {
1347
+ class: ['vxe-checkbox--icon', isChecked ? getIcon().CHECKBOX_CHECKED : getIcon().CHECKBOX_UNCHECKED]
1348
+ })
1349
+ ])
1350
+ }
1351
+ return renderEmptyElement($xeList)
1352
+ }
1353
+
1354
+ const renderRow = (row: any, rowIndex: any) => {
1355
+ const { showRadio, showCheckbox } = props
1356
+ const { selectRadioRow, currRowFlag, updateCheckboxFlag } = reactData
1357
+ const { selectCheckboxMaps, currentRow } = internalData
1358
+ const contentSlot = slots.content
1359
+ const dragOpts = computeDragOpts.value
1360
+ const { trigger, icon, disabledMethod, visibleMethod } = dragOpts
1361
+ const rowOpts = computeRowOpts.value
1362
+ const { useKey, contentField, className: rowClassName, isCurrent } = rowOpts
1363
+ const isDrag = computeIsDrag.value
1364
+ const keyField = computeKeyField.value
1365
+ const isRowFnCls = rowClassName && XEUtils.isFunction(rowClassName)
1366
+
1367
+ const hasKey = keyField || useKey || isDrag || isCurrent || showRadio || showCheckbox
1368
+
1369
+ const rowKey = hasKey && keyField ? getRowIdByField(row, keyField) : ''
1370
+ const rowid = enModelValue(rowKey)
1371
+ const rowParams = { row, $list: $xeList }
1372
+
1373
+ let isRadioChecked = false
1374
+ if (showRadio) {
1375
+ isRadioChecked = selectRadioRow && (row === selectRadioRow || eqRowByKey(selectRadioRow, rowKey))
1376
+ }
1377
+
1378
+ let isCheckboxChecked = false
1379
+ if (showCheckbox) {
1380
+ isCheckboxChecked = !!(updateCheckboxFlag && selectCheckboxMaps[rowid])
1381
+ }
1382
+
1383
+ const ctVNs: VNode[] = []
1384
+ let isDragDisabled = false
1385
+ if (isDrag && keyField && (!visibleMethod || visibleMethod(rowParams))) {
1386
+ const handleOns: {
1387
+ onMousedown?: (evnt: MouseEvent) => void
1388
+ onMouseup?: (evnt: MouseEvent) => void
1389
+ } = {}
1390
+ if (trigger !== 'row') {
1391
+ isDragDisabled = !!(disabledMethod && disabledMethod(rowParams))
1392
+ handleOns.onMousedown = (evnt) => {
1393
+ if (!isDragDisabled) {
1394
+ handleRowDragMousedownEvent(evnt, rowParams)
1395
+ }
1396
+ }
1397
+ handleOns.onMouseup = handleRowDragMouseupEvent
1398
+ }
1399
+ ctVNs.push(
1400
+ h('div', {
1401
+ key: 'ct1',
1402
+ class: 'vxe-list--row-drag'
1403
+ }, [
1404
+ h('span', {
1405
+ class: 'vxe-list--drag-handle',
1406
+ ...handleOns
1407
+ }, [
1408
+ h('i', {
1409
+ class: icon || getIcon().LIST_DRAG
1410
+ })
1411
+ ])
1412
+ ])
1413
+ )
1414
+ }
1415
+ if (showRadio) {
1416
+ ctVNs.push(
1417
+ renderRadio(row, rowid, isRadioChecked)
1418
+ )
1419
+ }
1420
+ if (showCheckbox) {
1421
+ ctVNs.push(
1422
+ renderCheckbox(row, rowid, isCheckboxChecked)
1423
+ )
1424
+ }
1425
+ ctVNs.push(
1426
+ h('div', {
1427
+ key: 'ct5',
1428
+ class: 'vxe-list--row-content'
1429
+ }, contentSlot ? contentSlot(rowParams) : (contentField ? getText(row[contentField]) : ''))
1430
+ )
1431
+
1432
+ const rowOns: {
1433
+ onMousedown: (evnt: MouseEvent) => void
1434
+ onMouseup: (evnt: MouseEvent) => void
1435
+ onClick: (evnt: MouseEvent) => void
1436
+ onDblclick: (evnt: MouseEvent) => void
1437
+ onDragstart?: (evnt: DragEvent) => void
1438
+ onDragend?: (evnt: DragEvent) => void
1439
+ onDragover?: (evnt: DragEvent) => void
1440
+ } = {
1441
+ onMousedown (evnt: MouseEvent) {
1442
+ handleRowMousedownEvent(evnt, row)
1443
+ },
1444
+ onMouseup: handleRowDragMouseupEvent,
1445
+ onClick (evnt: MouseEvent) {
1446
+ handleRowClickEvent(evnt, row)
1447
+ },
1448
+ onDblclick (evnt: MouseEvent) {
1449
+ handleRowDblclickEvent(evnt, row)
1450
+ }
1451
+ }
1452
+ // 拖拽行事件
1453
+ if (isDrag) {
1454
+ rowOns.onDragstart = handleRowDragDragstartEvent
1455
+ rowOns.onDragend = handleRowDragDragendEvent
1456
+ rowOns.onDragover = handleRowDragDragoverEvent
1457
+ }
1458
+
1459
+ return h('div', {
1460
+ key: hasKey && keyField ? rowid : rowIndex,
1461
+ class: ['vxe-list--row', isRowFnCls ? rowClassName(rowParams) : (rowClassName || ''), {
1462
+ 'is--drag-disabled': isDragDisabled,
1463
+ 'is--current': currRowFlag && currentRow && eqRowByKey(currentRow, rowKey),
1464
+ 'is-radio--checked': isRadioChecked,
1465
+ 'is-checkbox--checked': isCheckboxChecked
1466
+ }],
1467
+ rowid: hasKey && keyField ? rowid : undefined,
1468
+ ...rowOns
1469
+ }, ctVNs)
1470
+ }
332
1471
 
333
1472
  const renderVN = () => {
334
- const { className, loading } = props
335
- const { bodyHeight, topSpaceHeight, items } = reactData
1473
+ const { showCheckbox, className, loading } = props
1474
+ const { bodyHeight, topSpaceHeight, rowList, isAllChecked, isAllIndeterminate } = reactData
336
1475
  const defaultSlot = slots.default
1476
+ const headerSlot = slots.header
1477
+ const footerSlot = slots.footer
337
1478
  const vSize = computeSize.value
338
- const styles = computeStyles.value
1479
+ const wrapperStyles = computeWrapperStyles.value
1480
+ const virtualStyles = computeVirtualStyles.value
1481
+ const radioOpts = computeRadioOpts.value
1482
+ const checkboxOpts = computeCheckboxOpts.value
1483
+ const { showHeader, headerTitle } = checkboxOpts
1484
+ const dragOpts = computeDragOpts.value
1485
+ const { trigger } = dragOpts
1486
+ const rowOpts = computeRowOpts.value
1487
+ const { isHover, padding } = rowOpts
1488
+ const isDrag = computeIsDrag.value
1489
+ const showDefChekboxHead = showCheckbox && showHeader !== false
339
1490
  return h('div', {
340
1491
  ref: refElem,
341
1492
  class: ['vxe-list', className ? (XEUtils.isFunction(className) ? className({ $list: $xeList }) : className) : '', {
342
1493
  [`size--${vSize}`]: vSize,
1494
+ 'is--drag': isDrag,
343
1495
  'is--loading': loading
344
- }]
1496
+ }],
1497
+ style: wrapperStyles
345
1498
  }, [
1499
+ headerSlot || showDefChekboxHead
1500
+ ? h('div', {
1501
+ ref: refHeaderElem,
1502
+ class: 'vxe-list--header-wrapper'
1503
+ }, [
1504
+ showDefChekboxHead
1505
+ ? h('div', {
1506
+ class: 'vxe-list--header-left'
1507
+ }, [
1508
+ h('div', {
1509
+ class: ['vxe-list--checkbox-header', {
1510
+ 'is--checked': isAllChecked,
1511
+ 'is--indeterminate': isAllIndeterminate
1512
+ }],
1513
+ onClick: changeCheckboxAllEvent
1514
+ }, [
1515
+ h('span', {
1516
+ class: ['vxe-checkbox--icon', isAllChecked ? getIcon().CHECKBOX_CHECKED : (isAllIndeterminate ? getIcon().CHECKBOX_INDETERMINATE : getIcon().CHECKBOX_UNCHECKED)]
1517
+ }),
1518
+ h('span', {
1519
+ class: 'vxe-checkbox--label'
1520
+ }, XEUtils.eqNull(headerTitle) ? getI18n('vxe.list.allChecked') : getText(headerTitle))
1521
+ ])
1522
+ ])
1523
+ : renderEmptyElement($xeList),
1524
+ headerSlot
1525
+ ? h('div', {
1526
+ class: 'vxe-list--header-content'
1527
+ }, headerSlot({ items: rowList, $list: $xeList }))
1528
+ : renderEmptyElement($xeList)
1529
+ ])
1530
+ : renderEmptyElement($xeList),
346
1531
  h('div', {
347
1532
  ref: refVirtualWrapper,
348
1533
  class: 'vxe-list--virtual-wrapper',
349
- style: styles,
1534
+ style: virtualStyles,
350
1535
  onScroll: scrollEvent
351
1536
  }, [
352
1537
  h('div', {
@@ -357,12 +1542,28 @@ export default defineVxeComponent({
357
1542
  }),
358
1543
  h('div', {
359
1544
  ref: refVirtualBody,
360
- class: 'vxe-list--body',
1545
+ class: ['vxe-list--body', {
1546
+ 'trigger--row': trigger === 'row',
1547
+ 'checkbox--highlight': checkboxOpts.highlight,
1548
+ 'radio--highlight': radioOpts.highlight,
1549
+ 'row--hover': isHover,
1550
+ 'is--padding': padding
1551
+ }],
361
1552
  style: {
362
1553
  marginTop: topSpaceHeight ? `${topSpaceHeight}px` : ''
363
1554
  }
364
- }, defaultSlot ? defaultSlot({ items, $list: $xeList }) : [])
1555
+ }, defaultSlot ? defaultSlot({ items: rowList, $list: $xeList }) : rowList.map((row, i) => renderRow(row, i)))
365
1556
  ]),
1557
+ footerSlot
1558
+ ? h('div', {
1559
+ ref: refFooterElem,
1560
+ class: 'vxe-list--footer-wrapper'
1561
+ }, footerSlot({ items: rowList, $list: $xeList }))
1562
+ : renderEmptyElement($xeList),
1563
+ /**
1564
+ * 拖拽提示
1565
+ */
1566
+ renderDragTip(),
366
1567
  /**
367
1568
  * 加载中
368
1569
  */
@@ -384,19 +1585,38 @@ export default defineVxeComponent({
384
1585
  loadData(props.data || [])
385
1586
  })
386
1587
 
1588
+ const reFlag = ref(0)
387
1589
  watch(() => props.height, () => {
388
- recalculate()
1590
+ reFlag.value++
389
1591
  })
390
-
391
1592
  watch(() => props.maxHeight, () => {
392
- recalculate()
1593
+ reFlag.value++
393
1594
  })
394
-
395
- watch(() => props.syncResize, (value) => {
396
- if (value) {
1595
+ watch(() => props.syncResize, () => {
1596
+ reFlag.value++
1597
+ })
1598
+ watch(computeRowHeight, () => {
1599
+ reFlag.value++
1600
+ })
1601
+ watch(reFlag, () => {
1602
+ nextTick(() => {
397
1603
  recalculate()
398
- nextTick(() => setTimeout(() => recalculate()))
399
- }
1604
+ })
1605
+ })
1606
+
1607
+ watch(() => props.checkRowKey, () => {
1608
+ updateRadioModeValue()
1609
+ })
1610
+
1611
+ const checkKeyFlag = ref(0)
1612
+ watch(() => props.checkRowKeys ? props.checkRowKeys.length : -1, () => {
1613
+ checkKeyFlag.value++
1614
+ })
1615
+ watch(() => props.checkRowKeys, () => {
1616
+ checkKeyFlag.value++
1617
+ })
1618
+ watch(checkKeyFlag, () => {
1619
+ updateCheckboxModeValue()
400
1620
  })
401
1621
 
402
1622
  onActivated(() => {
@@ -408,8 +1628,26 @@ export default defineVxeComponent({
408
1628
  })
409
1629
 
410
1630
  onMounted(() => {
411
- recalculate()
1631
+ const { showRadio, showCheckbox } = props
1632
+ const rowOpts = computeRowOpts.value
1633
+ const { useKey } = rowOpts
412
1634
 
1635
+ const isDrag = computeIsDrag.value
1636
+ const keyField = computeKeyField.value
1637
+ if (!keyField) {
1638
+ if (showRadio) {
1639
+ errLog('vxe.error.reqSupportProp', ['show-radio', 'row-config.keyField'])
1640
+ }
1641
+ if (showCheckbox) {
1642
+ errLog('vxe.error.reqSupportProp', ['show-checkbox', 'row-config.keyField'])
1643
+ }
1644
+ if (isDrag) {
1645
+ errLog('vxe.error.reqSupportProp', ['drag-config', 'row-config.keyField'])
1646
+ }
1647
+ }
1648
+ if (useKey && !keyField) {
1649
+ errLog('vxe.error.reqSupportProp', ['row-config.useKey', 'row-config.keyField'])
1650
+ }
413
1651
  if (props.autoResize) {
414
1652
  const el = refElem.value
415
1653
  const resizeObserver = globalResize.create(() => recalculate())
@@ -419,6 +1657,7 @@ export default defineVxeComponent({
419
1657
  }
420
1658
  internalData.resizeObserver = resizeObserver
421
1659
  }
1660
+ recalculate()
422
1661
  globalEvents.on($xeList, 'resize', recalculate)
423
1662
  })
424
1663