treeSelect.jsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import React, { useMemo, useState, useCallback } from 'react';
  2. import { get, union, pullAll } from 'lodash';
  3. import { Table } from '@douyinfe/semi-ui';
  4. const childrenRecordName = 'children';
  5. const rowKey = 'key';
  6. const getKey = record => get(record, rowKey, 'key');
  7. const ChildrenDataSelectedDemo = () => {
  8. const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  9. const columns = useMemo(
  10. () => [
  11. {
  12. title: 'Key',
  13. dataIndex: 'dataKey',
  14. key: 'dataKey',
  15. },
  16. {
  17. title: '名称',
  18. dataIndex: 'name',
  19. key: 'name',
  20. width: 200,
  21. },
  22. {
  23. title: '数据类型',
  24. dataIndex: 'type',
  25. key: 'type',
  26. width: 400,
  27. },
  28. {
  29. title: '描述',
  30. dataIndex: 'description',
  31. key: 'description',
  32. },
  33. {
  34. title: '默认值',
  35. dataIndex: 'default',
  36. key: 'default',
  37. width: 100,
  38. },
  39. ],
  40. []
  41. );
  42. const data = useMemo(
  43. () => [
  44. {
  45. key: 1,
  46. dataKey: 'videos_info',
  47. name: '视频信息',
  48. type: 'Object 对象',
  49. description: '视频的元信息',
  50. default: '无',
  51. children: [
  52. {
  53. key: 11,
  54. dataKey: 'status',
  55. name: '视频状态',
  56. type: 'Enum <Integer> 枚举',
  57. description: '视频的可见、推荐状态',
  58. default: '1',
  59. },
  60. {
  61. key: 12,
  62. dataKey: 'vid',
  63. name: '视频 ID',
  64. type: 'String 字符串',
  65. description: '标识视频的唯一 ID',
  66. default: '无',
  67. children: [
  68. {
  69. key: 121,
  70. dataKey: 'video_url',
  71. name: '视频地址',
  72. type: 'String 字符串',
  73. description: '视频的唯一链接',
  74. default: '无',
  75. },
  76. ],
  77. }
  78. ],
  79. },
  80. {
  81. key: 2,
  82. dataKey: 'text_info',
  83. name: '文本信息',
  84. type: 'Object 对象',
  85. description: '视频的元信息',
  86. default: '无',
  87. children: [
  88. {
  89. key: 21,
  90. dataKey: 'title',
  91. name: '视频标题',
  92. type: 'String 字符串',
  93. description: '视频的标题',
  94. default: '无',
  95. },
  96. {
  97. key: 22,
  98. dataKey: 'video_description',
  99. name: '视频描述',
  100. type: 'String 字符串',
  101. description: '视频的描述',
  102. default: '无',
  103. }
  104. ],
  105. },
  106. ],
  107. []
  108. );
  109. // 自定义禁用逻辑
  110. const isRecordDisabled = (record) => {
  111. return false;
  112. };
  113. const traverse = (data, res) => {
  114. for (let record of data) {
  115. const children = get(record, 'children');
  116. const disabled = isRecordDisabled(record);
  117. if (!disabled) {
  118. const key = getKey(record);
  119. res.push(key);
  120. }
  121. if (Array.isArray(children)) {
  122. traverse(children, res);
  123. }
  124. }
  125. };
  126. const getAllRowKeys = data => {
  127. const allRowKeys = [];
  128. traverse(data, allRowKeys);
  129. console.log('allRowKeys', allRowKeys);
  130. return allRowKeys;
  131. };
  132. const findShouldSelectRowKeys = (record, selected) => {
  133. let shouldSelectRowKeys;
  134. const children = get(record, 'children');
  135. let childrenRowKeys = [];
  136. if (Array.isArray(children)) {
  137. traverse(children, childrenRowKeys);
  138. }
  139. const key = getKey(record);
  140. if (!selected) {
  141. shouldSelectRowKeys = [...selectedRowKeys];
  142. pullAll(shouldSelectRowKeys, [key, ...childrenRowKeys]);
  143. } else {
  144. shouldSelectRowKeys = union(selectedRowKeys, [key, ...childrenRowKeys]);
  145. }
  146. return shouldSelectRowKeys;
  147. };
  148. // 选中一行时需要选中自己可选行
  149. const doSelect = useCallback((record, selected) => {
  150. const rowKeys = findShouldSelectRowKeys(record, selected);
  151. setSelectedRowKeys(rowKeys);
  152. console.log('select', record, rowKeys);
  153. }, [selectedRowKeys, rowKey, childrenRecordName]);
  154. // 找出所有可选的行
  155. const doSelectAll = useCallback((selected, selectedRows) => {
  156. console.log(selected);
  157. let rowKeys = [];
  158. if (selected) {
  159. rowKeys = getAllRowKeys(data);
  160. }
  161. setSelectedRowKeys(rowKeys);
  162. }, []);
  163. const rowSelection = useMemo(
  164. () => ({
  165. selectedRowKeys,
  166. onSelect: doSelect,
  167. onSelectAll: doSelectAll,
  168. }),
  169. [selectedRowKeys, doSelect, doSelectAll]
  170. );
  171. return (
  172. <Table
  173. columns={columns}
  174. rowKey={rowKey}
  175. childrenRecordName={childrenRecordName}
  176. rowSelection={rowSelection}
  177. dataSource={data}
  178. pagination={false}
  179. />
  180. );
  181. };
  182. render(ChildrenDataSelectedDemo);