【React+antd】做一个自定义列的组件

前言:因为我是半途接手,之前的前端已经做了一部分,所以有些东西是二次修改,代码冗余之类的请勿在意(功能实现就好),只是一个小总结,有空优化~

效果:

 

 基本功能:左侧定位栏(大类),中间checkbox.group用来选择,右侧展示已选择的数据&&排序&删除功能,上面搜索列

 

首先我们需要的数据先定义一下:

 

1
2
3
4
5
6
7
8
9
state: ProState = {
  active: null, // 用来设置初始化首位
  indicatorsListRef: {}, // 用于定位
  checkIndicatorsList: [], //用来存储传入格式的数组
  defaultIndicatorsList: [], // 用来存储右边选中数组
  checkArr: this.props.checkArr || [], // 传入的全部数据,大类里包着对应数据的格式
  navList: this.props.navList || [], // 标题数组
  itemOrder: this.props.itemOrder || [] // 传入-右边选中数组
};

  

传入的数据格式是这样的:

 

 所以我们为了方便右边已选列表展示,定义一个方法来获取勾选结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * @description  获取勾选结果
 * @param {array} data  勾选的数据
 */
getDefaultList = (data: any) => {
  const resultArr: any[] = [];
  data && data.forEach((check: any) => {
    if (check.defaultCheckedList) {
      resultArr.push(check.defaultCheckedList);
    }
  });
  const list: any[] = resultArr && resultArr.length > 0&& resultArr.reduce((pre: any, next: any) => {
    return pre.concat(next);
  });
  return list;
};

  

格式是这样的:

 

jsx是这样滴:

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
renderContent = () => {
  const {
    active,
    checkIndicatorsList,
    indicatorsListRef,
    defaultIndicatorsList,
    navList,
  } = this.state;
 
  return (
    <>
      <div style={{ display: 'flex' }}>
        <div className={styles['m-add-indicators']}>
          <TheListTitle title="可添加的指标">
            <Search
              placeholder="请输入列名称搜索"
              // onChange={this.searchColumnChange}
              onSearch={this.searchColumn}
              style={{ width: 300 }}
            />
          </TheListTitle>
          <div style={{ display: 'flex' }}>
            <div className={styles['m-add-indicators-nav']}>
              {navList.map((item: any) => {
                return (
                  <div className={styles['m-add-indicators-nav-item']} key={item.id}>
                    <div className={styles['m-add-indicators-nav-title']}> {item.value}</div>
                    {item.subList &&
                      item.subList.map((el: any) => {
                        return (
                          <div
                            className={`${styles['m-add-indicators-nav-subtitle']} ${
                              active && active.id === el.id
                                ? styles['m-add-indicators-nav-subtitle-active']
                                : ''
                            }`}
                            key={el.id}
                            onClick={() => this.handleAnchor(el)}
                          >
                            {el.label}
                          </div>
                        );
                      })}
                  </div>
                );
              })}
            </div>
            <div
              className={styles['m-select-content']}
              ref={(el: any) => {
                this.checkboxRef = el;
              }}
              style={{position:'relative'}}
            >
              {checkIndicatorsList.map((item: any) => {
                return (
                  <div
                    ref={(el: any) => {
                      indicatorsListRef[item.id] = el;
                    }}
                    key={item.id}
                  >
                    <div className={`${styles['m-select-item']}${item.list.filter((item:any)=>item.hidden === false).length > 0 ? ` m-select-item-show` : ` m-select-item-hidden`}`}>
                      <BasisCheckbox
                        allName={item.label}
                        plainOptions={item.list}
                        defaultCheckedList={item.defaultCheckedList || []}
                        getGroupCheckedResult={(values) => {
                          this.getGroupCheckedResult(values, item);
                        }}
                      />
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
        <DragResultList list={defaultIndicatorsList} deleteItem={this.deleteItem} />
         
      </div>
    </>
  );
};

  

定义一个初始化列表的方法,以及处理数据更新时触发数据重新渲染:

 

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
/**
 * @description 页面初始化加载
 */
componentDidMount() {
  this.initList();
}
  /**
 * @description 页面props更新
 */
componentWillReceiveProps(nextProps:any) {
  // 如果不是第一次数据改变,不触发重初始化
  const { checkArr }  =this.state;
  if(JSON.stringify(nextProps.checkArr) === JSON.stringify(checkArr)) return;
  this.setState({
    checkArr: nextProps.checkArr,
    navList: nextProps.navList,
    itemOrder: nextProps.itemOrder
  },() => {
    this.initList();
  });
 }
initList = () =>{
  const {navList , checkArr, itemOrder } = this.state;
  if (navList && navList.length > 0 && navList[0].subList) {
    // 设置初始化首位
    this.setState({
      active: navList[0].subList[0],
    });
  }
  // 默认选中项列表
  checkArr && checkArr.length > 0 && checkArr.forEach((item: any) => {
    item.defaultCheckedList = item.list && item.list.filter((el: any) => el.state === 1);
    item.list && item.list.forEach((el: any) => { el.hidden = false });
  });
  let initItemOrder:any = [];
  if(itemOrder && itemOrder.length && itemOrder.length > 0){
    initItemOrder = itemOrder && itemOrder.map((el: any) => {
      return {...el,hidden: false}
    })
  }else {
    initItemOrder = this.getDefaultList(checkArr) && this.getDefaultList(checkArr).map((el: any) => {
      return {...el,hidden: false}
    })
  }
   
  this.setState({
    checkIndicatorsList: checkArr,
    defaultIndicatorsList: initItemOrder || []
  });
}

  

关于中间那块的数据改变,页面会返回对应的values(之前的大佬写的),这个values包括了两个数组,defaultList和checkedList,但是它defaultList就是当前这个group的对象数组,checkedList就是id的数组,如果这个group没有选中东西,它就是空的,对外层的使用略不友好,尽管如此因为实在没时间去重构了所以我直接用了QAQ,外层定义一个checkbox.group改变时的callback的方法:

 

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
  /**
   * @description  checkbox 结果
   * @param {any} values
   *  @param {any} item  项
   */
  getGroupCheckedResult = (values: any, item: any) => {
    const { checkIndicatorsList,  defaultIndicatorsList } = this.state;
    checkIndicatorsList.forEach((el: any) => {
      if (el.id === item.id) {
        el.defaultCheckedList = values.defaultList;
      }
    });
    // 新的数组>旧的数组 => add
    if(this.getDefaultList(checkIndicatorsList).length >  defaultIndicatorsList.length){
      const resIDs = defaultIndicatorsList.map(item => item.id)
      // 新增的
      const diff = this.getDefaultList(checkIndicatorsList).filter(item => !resIDs.includes(item.id))
      this.setState({
        defaultIndicatorsList: defaultIndicatorsList.concat([...diff]),
      });
    }else{
      const resIDs = this.getDefaultList(checkIndicatorsList).map(item => item.id)
      // 删掉的
      const diff =  defaultIndicatorsList.filter(item => !resIDs.includes(item.id))
      const diffIDs = diff.map(item => item.id)
      const newArr  =  defaultIndicatorsList.filter(item => !diffIDs.includes(item.id))
      this.setState({
        defaultIndicatorsList: newArr,
      });
    }
     
  };

  

也就是其实实际右侧的展示其实是直接通过返回的values.defaultList跟源数据进行了处理,然后通过getDefaultList获取到了目前整个中间选中的项。

因为每次操作都只是增加或者删除单独的一项,我们就得到了onChange之后的值并且进行了处理和展示,所以我的逻辑很简单:

如果是增加,那么新旧数组之差集就是新增的,通过filter筛选出来新数组返回来的这条新增的数据(因为是条对象),concat接到旧数组后面,这样就可以按照添加的顺序依次展示在右侧了~

如果是删除,那么新旧数组之差集就是删除的,把这一项的id获取到,filter出旧数组id不等于这个id的其他项保存,就正常删除了~如果是普通数组就更方便了,splice(id,1)舒服的要死 TAT

 

实现了中间对已选栏的增删后,就是已选栏自己的删除和排序了,在大佬封装的DragResultList这个组件里,删除返回的是当前item对象,清空返回的是-1,所以外层删除的方法就是这样:

 

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
/**
 * @description  删除项
 * @param {object | number } item  项 -1全部
 */
deleteItem = (item: any) => {
  const { checkIndicatorsList, defaultIndicatorsList } = this.state;
  // -1 === 清空
  if (item !== -1) {
    checkIndicatorsList.forEach((check: any) => {
      if (check.defaultCheckedList) {
        check.defaultCheckedList = check.defaultCheckedList.filter((el: any) => el.id !== item.id);
      }
    });
    this.setState({
      defaultIndicatorsList: defaultIndicatorsList && defaultIndicatorsList.filter((element:any)=> element.id !== item.id ),
    });
  } else {
    checkIndicatorsList.forEach((check: any) => {
      check.defaultCheckedList = [];
    });
    this.setState({
      defaultIndicatorsList: [],
    });
  }
};

  

哦还有搜索列功能~:

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
/**
 * 搜索列名称
 * @param {string} value  - 搜索的值
 */
searchColumn = (value: string) => {
  this.setState({
    searchColumnValue: value
  })
  const { checkIndicatorsList } = this.state;
    const newCheckArr = JSON.parse(JSON.stringify(checkIndicatorsList))
    // 默认选中项列表
    newCheckArr && newCheckArr.length > 0 && newCheckArr.forEach((item: any) => {
      item.defaultCheckedList = item.list && item.list.filter((el: any) => el.state === 1);
      item.list && item.list.forEach((el: any) => {
        if(el.value.indexOf(value) !== -1){
          el.hidden = false
        }else{
          el.hidden = true
        }
      });
    });
    this.setState({
      checkIndicatorsList: newCheckArr,
    });
};

  

这里就是我们为什么初始化的时候全部统一给数据加上hidden为false的原因了,因为这个hidden属性是用来控制是否展示的!(夸一下机智的我)

看看效果:

 

 然后就是提交数据了,这个没有什么好说的,给父组件一个是全部数据,一个是排序数据,父组件那边可以随便选用:

 

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
/**
 * @description 确定
 */
onSubmit = async () => {
  const { channelId } = this.props;
  if (!channelId) return;
  const { checkIndicatorsList, defaultIndicatorsList } = this.state;
  // 处理当前选中的指标项数据,提交
  const newList = checkIndicatorsList.map((item:any) => {
    let newObj = { id: item.id, label: item.label, list: [] as any };
    item.list && item.list.forEach((listItem:any) => {
      const newItem = {
        id: listItem.id,
        value: listItem.value,
        state: 0,
        isOrder: listItem.isOrder,
      };
      defaultIndicatorsList && defaultIndicatorsList.forEach((obj:any) => {
        if (newItem.id == obj.id) {
          newItem.state = 1;
        }
      })
      newObj.list.push(newItem)
    })
    return newObj
  });
  if(this.props.onSubmitCallback) this.props.onSubmitCallback(newList, defaultIndicatorsList)
};

  

至于右侧的拖拽列表(DragResultList)组件不是我写的,也附上代码一起学习叭:

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
// 第三方库
import React, { useEffect, useState } from 'react';
import { Space } from 'antd';
import {
  UnorderedListOutlined,
  LockOutlined,
  DeleteOutlined,
  VerticalAlignTopOutlined,
} from '@ant-design/icons';
 
// 组件
import { BasisEmpty } from '@/components/index';
import { TheCardDragList, TheListTitle } from '@/modules';
 
// 类型声明
import { Props } from './index.type';
 
// 样式
import styles from './style.less';
 
// 交换数组索引位置位置
function swapPositions(arr: any[], preIndex: number, nextIndex: number) {
  arr[preIndex] = arr.splice(nextIndex, 1, arr[preIndex])[0];
  return arr;
}
 
// 拖拽列表
const DragResultList: React.FC<Props> = (props) => {
  const { list, deleteItem } = props;
  // 结果列表
  const [resultList, setResultList] = useState<any[]>([]);
  // 置顶Id
  const [unTopId, setUnTopId] = useState<number>(-1);
 
  /**
   * 设置为置顶
   * @param {array} data -数据
   */
  const setTopId = (data: any[]) => {
    if(data.length !== 0){
      // 非固定数组
      const unfixArr: any[] = data.filter((el: any) => !el.disabled);
      if (unfixArr && unfixArr.length > 0) {
        setUnTopId(unfixArr[0].id);
      }
    }else{
      setUnTopId(-1);
    }
  };
 
  useEffect(() => {
    // if (list && list.length > 0) {
    setResultList(list);
    setTopId(list);
    // }
  }, [list]);
 
  /**
   * 删除
   * @param {object} data -删除的项
   */
  const handleDelete = (data: any) => {
    deleteItem && deleteItem(data);
  };
 
  /**
   * 向上置顶
   * @param {object} data -置顶的项
   */
  const handlePlaceTop = (data: any) => {
    // 需要置顶的项
    const preIndex: number = resultList.findIndex((el: any) => el.id === data.id);
    // 当前置顶
    const nowIndex: number = resultList.findIndex((el: any) => el.id === unTopId);
 
    if (nowIndex !== -1) {
      const arr: any = swapPositions(resultList, preIndex, nowIndex);
      setResultList(arr);
      const unfixArr: any[] = arr.filter((el: any) => !el.disabled);
      setUnTopId(unfixArr[0].id);
    }
  };
 
  /**
   *  获取拖拽结果
   * @param {array} data -拖拽数据
   */
  const getDrageList = (data: any[]) => {
    setResultList(data);
    setTopId(data);
  };
 
  /**
   * 构建卡片
   * @param {object} item -卡片项
   */
  const renderCardItem = (item: any) => {
    return (
      <div className={styles['m-card-item']}>
        {!item.disabled ? <UnorderedListOutlined style={{ cursor: 'move' }} /> : <LockOutlined />}
        <div className={`${styles['m-card-item-title']} ${!item.disabled ? 'cursor_move' : ''}`}>
          {item.value}
        </div>
        {!item.disabled && (
          <Space>
            {unTopId !== item.id && (
              <VerticalAlignTopOutlined
                style={{ cursor: 'pointer' }}
                onClick={() => handlePlaceTop(item)}
              />
            )}
            <DeleteOutlined style={{ cursor: 'pointer' }} onClick={() => handleDelete(item)} />
          </Space>
        )}
      </div>
    );
  };
 
  // 构建已选结果
  const renderList = () => {
    return resultList && resultList.length > 0 ? (
      <TheCardDragList
        className={styles['m-drag-list']}
        list={resultList}
        renderCardItem={renderCardItem}
        getDrageList={getDrageList}
      />
    ) : (
      <BasisEmpty />
    );
  };
  return (
    <div className={styles['m-drag-result']}>
      <TheListTitle list={resultList} clearItems={handleDelete} />
      {renderList()}
    </div>
  );
};
 
export default DragResultList;

  

而左边的定位功能其实体验不太好,因为没有滚动效果,只是直接定位了中间的位置,但也记录一下大佬的代码共同学习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * @description  定位
 * @param {object} item  项
 */
handleAnchor = (item: any) => {
  this.setState({
    active: item,
  });
  const { indicatorsListRef } = this.state;
  const keysList: any[] = Object.keys(indicatorsListRef);
  if (indicatorsListRef[item.id] && keysList.length > 0) {
    this.checkboxRef.scrollTop =
      indicatorsListRef[item.id].offsetTop - indicatorsListRef[keysList[0]].offsetTop;
  }
};

  
关于这个我觉得也许可以考虑用antd的锚点组件,但是实在没空了QAQ回头有时间试一下

补充:

经过师傅的提醒,在中间的包裹层加scroll-behavior: smooth;这个样式,即可有滚动效果,滚动中间高亮左边可用 IntersectionObserver。

因为我是点击左边定位,没有滚动包裹层高亮的需求,因此不做赘述。

e.g.

学习文档:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver

阮一峰:http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html

 

顺便大佬的BaseCheckbox的代码也贴一下,基本没改什么:

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// 第三方库
import _ from 'lodash';
import { Checkbox, Tooltip } from 'antd';
import React, { useState, useEffect } from 'react';
 
// 类型声明
import { Props, CheckProps } from './index.type';
 
// 样式
import styles from './style.less';
 
const { Group } = Checkbox;
 
const BaseCheckbox: React.FC<Props> = (props) => {
  // 父级数据
  const {
    plainOptions,
    defaultCheckedList,
    showAll,
    showTip,
    limit,
    disabled,
    allName,
    showDefault,
    defaultSystem,
    getGroupCheckedResult,
  } = props;
   
  // 默认的id
  const formattedCheckedList = defaultCheckedList && defaultCheckedList.map((item) => item.id);
 
  // disabled 的 id
  const disabledCheckedList =
    plainOptions && plainOptions.filter((item: any) => item.disabled).map((item) => item.id);
 
  // 初始化数据
  const [state, setState] = useState<CheckProps>({
    plainOptions: [],
    checkedList: [],
    indeterminate: false,
    checkAll: false,
  });
 
  // 全选
  const [allValuesChecked, setAllValuesChecked] = useState([]);
 
  //默认
  const [checkDefault, setDefaultCheck] = useState<any>(true);
 
  /**
   * @description 依赖默认项 与初始化数据
   */
  useEffect(() => {
    if (plainOptions) {
      const formattedValues = plainOptions.map((item) => {
        return { label: item.value, value: item.id, ...item };
      });
      // @ts-ignore
      setAllValuesChecked(() => {
        return plainOptions.map((item) => {
          return item.id;
        });
      });
 
      setState({
        plainOptions: formattedValues,
        checkedList: formattedCheckedList,
        indeterminate:
          !!formattedCheckedList.length && formattedCheckedList.length < plainOptions.length,
        checkAll: formattedCheckedList.length === plainOptions.length,
      });
    }
  }, [defaultCheckedList, plainOptions]);
 
  // 监听点击事件 超过个数禁止点击
  useEffect(() => {
    if (!limit) return;
 
    // 如果超过个数 未选中的 disabled true
    if (state.checkedList && state.checkedList.length === limit) {
      _.forEach(plainOptions, (o: any) => {
        if (_.includes(state.checkedList, o.id)) {
          o.disabled = false;
        } else {
          o.disabled = true;
        }
      });
    } else {
      _.forEach(plainOptions, (o: any) => {
        o.disabled = false;
      });
    }
  }, [state.checkedList, plainOptions]);
 
  /**
   * 改变选择项
   * @param {array} checkedList - 已选的项
   * @return 已选项为选择的项
   */
  const onChange = (checkedList: any[]) => {
    // console.log(checkedList,'--checkedList-', plainOptions)
    // 传递给父级
    const defaultList = plainOptions
      .map((item: any) => {
        if (checkedList.includes(item.id)) {
          return item;
        }
        return null;
      })
      .filter((item) => item != null);
 
    const checkInfo = {
      ...state,
      checkedList,
      indeterminate: !!checkedList.length && checkedList.length < plainOptions.length,
      checkAll: checkedList.length === plainOptions.length,
    };
 
    setState(checkInfo);
    if (getGroupCheckedResult) {
      getGroupCheckedResult({
        defaultList,
        checkedList,
      });
    }
  };
 
  /**
   * @description 依赖全选 与所选项
   */
  useEffect(() => {
    if (showDefault) {
      setDefaultCheck(_.isEqual(state.checkedList, defaultSystem));
    }
  }, [state]);
 
  /**
   * @description 默认数据
   * @return 已选项为默认数据
   */
  const onCheckDefaultChange = () => {
    if (!defaultSystem) return;
 
    // props.changeDefautUse();
    return setState({
      ...state,
      indeterminate: !!defaultSystem.length && defaultSystem.length < plainOptions.length,
      checkAll: defaultSystem.length === plainOptions.length,
      checkedList: defaultSystem,
    });
  };
 
  /**
   * 全选
   * @param {object} event - 原生项
   * @return 已选项为全部选项
   */
  const onCheckAllChange = (e: any) => {
    // 控制全选的选项项
    const checkedArr: any[] = e.target.checked
      ? allValuesChecked
      : _.intersection(allValuesChecked, disabledCheckedList);
    // 传递给父级
    const defaultList = plainOptions
      .map((item: any) => {
        if (checkedArr.includes(item.id)) {
          return item;
        }
        return null;
      })
      .filter((item) => item != null);
    // 传递给父级
    if (getGroupCheckedResult) {
      getGroupCheckedResult({
        defaultList,
        checkedList: checkedArr,
        checkAll: true,
      });
    }
    setState({
      ...state,
      checkedList: checkedArr,
      indeterminate: false,
      checkAll: e.target.checked,
    });
  };
 
  // 全选与默认
  const handleCheckbox = () => {
    const unHideList:any[] = plainOptions && plainOptions.filter((item:any)=>item.hidden === false)
    const hiddenGroup = unHideList && unHideList.length > 0 ? false : true;
    return (
      !hiddenGroup &&
      <div>
        {showAll && (
          <Checkbox
            indeterminate={state.indeterminate}
            onChange={onCheckAllChange}
            checked={state.checkAll}
          >
            {allName || (state.checkAll ? '取消全选' : '全选')}
          </Checkbox>
        )}
        {showDefault && (
          <Checkbox onChange={onCheckDefaultChange} checked={checkDefault}>
            系统默认
          </Checkbox>
        )}
      </div>
    );
  };
 
  // checkbox组
  const renderGroup = () => {
    const unHideList:any[] = plainOptions && plainOptions.filter((item:any)=>item.hidden === false)
    const hiddenGroup = unHideList && unHideList.length > 0 ? false : true;
    return (
      <>
        {/* 带有提示Tooltip */}
        {showTip ? (
          !hiddenGroup &&
          <Group disabled={disabled} value={state.checkedList} onChange={onChange}>
            {plainOptions.map((o) => (
              <Tooltip title={o.nouns} key={o.id} >
                <Checkbox disabled={o.disabled} key={o.id} value={o.id} style={{display: o.hidden ? 'none' : 'inline-block'}}>
                  {o.value}
                </Checkbox>
              </Tooltip>
            ))}
          </Group>
        ) : (
          !hiddenGroup &&
          <Group disabled={disabled} value={state.checkedList} onChange={onChange}>
            {plainOptions.map((o) => (
              <Checkbox disabled={o.disabled} key={o.id} value={o.id} style={{display: o.hidden ? 'none' : 'inline-block'}}>
                {o.value}
                {o.lock}
              </Checkbox>
            ))}
          </Group>
        )}
      </>
    );
  };
  return (
    <div className={styles['c-base-checkbox']}>
      {state.plainOptions.length > 0 && (
        <>
          {showAll && handleCheckbox()}
          {renderGroup()}
        </>
      )}
    </div>
  );
};
 
// 默认
BaseCheckbox.defaultProps = {
  showAll: true,
  showTip: false,
  defaultCheckedList: [],
};
 
export default BaseCheckbox;

  

至此一个复杂的要死套来套去的自定义列组件就做好啦,呜呜呜呜

posted @   芝麻小仙女  阅读(1621)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示