使用antd的select实现动态增加多行以及禁用已选中数据

一、效果:

1.可动态增加当前行数据

2.当前行选中的数据在当前行下拉列表不禁用

3.禁用其他行选中的数据

二、踩坑

1.隐藏,会使节点所在地方白屏。

2.删除过滤,会使渲染的是选中的value值,而不是label

3.直接添加禁用属性,使选中不可单个删除

三、实现

定义hooks

const [storeHouse, setStoreHouse] = useState<any[]>([]);

使用form监听,使用onValuesChange监听form表单变化


 onValuesChange={(change: any, now: any) => {
 //change是改变的值,now是当前表单的数据
            if (change.xxx1) {
              // 判断当前字段最外层监听是否变化,xxx1是动态表单外层字段
              if (change.xxx1.filter((item: any) => item !== null)) {
                let arr: any[] = [];
                //将已填写表单数据循环
                now.xxx1
                  .forEach((item: any) => {
                    if (item?.xxx2) {
                      arr.push(item?.xxx2);
                    }
                  });
                    //数组使用set去重以及Arr.from转成数组形式
                const newArr = Array.from(new Set([...arr]));
                setStoreHouse(newArr);
              }
            }
          }}

3.动态增加,此处省略动态增加逻辑

<Form.List name="xxx1" initialValue={[{}]}>
                {(fields, { add, remove }) => (
                  <>
                    {fields.map(({ key, name, ...restField }, index) => (
                          <Form.Item
                            {...formItemLayout}
                            name={[name, 'repositoryIdList']}
                            label="A"
                          >
                            <Select
                              mode="multiple"//多选
                              allowClear
                              }
                            >
                              {xxx2.map((item: any) => {
//parthName获取当前字段值
                                const checkValue = form.getFieldValue([
                                  'xxx1',
                                  name,
                                  'xxx2',
                                ]);
                                if (storeHouse?.includes(item.value)) {
                                  if (checkValue?.includes(item.value)) {
                                    // 将当前行选中解除禁用
                                    return (
                                      <Option disabled={false} value={item.value} key={item.value}>
                                        {item.label}
                                      </Option>
                                    );
                                  } else {
                                    return (
                                      // 禁用其他行选中
                                      <Option disabled={true} value={item.value} key={item.value}>
                                        {item.label}
                                      </Option>
                                    );
                                  }

                                  //   { ...item, disabled: true };
                                } else {
                                  return (
                                    // 未选的仓库不禁用
                                    <Option value={item.value} key={item.value}>
                                      {item.label}
                                    </Option>
                                  );
                                }
                              })}

                              {/* <Option></Option> */}
                            </Select>
                          </Form.Item>
                    <Col span={22}>
                      <Button
                        type="dashed"
                        onClick={() => add()}
                        block
                        icon={<PlusOutlined />}
                      >
                        新增
                      </Button>
                    </Col>
                  </>
                )}
              </Form.List>

好的,对于您的问题,您可以使用 antd 的 TreeSelect 组件来实现带有所有父级节点的回显。下面是一个示例的代码: ``` <template> <a-tree-select v-model="selectedKeys" :tree-data="treeData" :tree-default-expand-all="true" :tree-checkable="true" :show-search="true" :tree-default-expanded-keys="defaultExpandedKeys" :tree-checked-keys="defaultCheckedKeys" :tree-icon="icon" :showCheckedStrategy="SHOW_PARENT" :placeholder="'Please select'" style="width: 100%" /> </template> <script> import { TreeSelect } from 'ant-design-vue'; export default { components: { 'a-tree-select': TreeSelect, }, data() { return { selectedKeys: [], defaultExpandedKeys: [], defaultCheckedKeys: [], treeData: [], }; }, created() { // 从后端获取树形结构数据 // 这里只是一个示例数据,您需要根据自己的业务逻辑来获取数据 this.treeData = [ { title: 'Node1', value: '0-0', key: '0-0', children: [ { title: 'Node1-1', value: '0-0-0', key: '0-0-0', }, { title: 'Node1-2', value: '0-0-1', key: '0-0-1', }, ], }, { title: 'Node2', value: '0-1', key: '0-1', children: [ { title: 'Node2-1', value: '0-1-0', key: '0-1-0', }, { title: 'Node2-2', value: '0-1-1', key: '0-1-1', }, ], }, ]; this.defaultExpandedKeys = ['0-0', '0-1', '0-0-0', '0-0-1']; this.defaultCheckedKeys = ['0-0-0']; }, methods: { icon({ isLeaf }) { return isLeaf ? 'file' : 'folder'; }, }, }; </script> ``` 这里使用了 TreeSelect 组件的 `showCheckedStrategy` 属性,将其设置为 `SHOW_PARENT`,可以实现带有所有父级节点的回显。另外,可以设置默认展开的节点和默认选中的节点,可以根据自己的业务逻辑来进行设置。希望能够帮到您!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值