【图文并茂】ant design pro 如何用 renderFormItem 结合 TreeSelect 实现一个多层树级搜索

在这里插入图片描述
在这里插入图片描述
上一篇 【图文并茂】ant design pro 如何优雅地实现查询列表功能

如上图所示

比如我们经常要查一些,商品分类下的所有的商品

类似这样的需求如何做。

我们以菜单为例,我们可以查找某个父类下的所有子菜单

当然最简单的做法,是提供一个 input text 框,让其输入菜单名称来查。

但是为了更好的用户体验,我们直接让客户去选,而不是输入菜单名

在这里插入图片描述

前端

前端的实现比较简单

直接上代码:

    {
      title: intl.formatMessage({ id: 'parent_category' }),
      dataIndex: ['parent', 'name'],
      // @ts-ignore
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      renderFormItem: (_, { type, defaultRender, formItemProps, fieldProps, ...rest }, form) => {
        if (type === 'form') {
          return null;
        }
        return (
          <TreeSelect
            showSearch
            style={{ width: '100%' }}
            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
            placeholder={intl.formatMessage({ id: 'select_parent_category' })}
            allowClear
            treeNodeFilterProp="name"
            fieldNames={{ label: 'name', value: '_id' }}
            treeDefaultExpandAll
            treeData={menus}
            loading={loading}
            {...fieldProps}
          />
        );
      },
    },

TreeSelect 中的数据肯定是查出来的

这个 menus 肯定是远程查询到的。

关于这块的内容可以看之前的文章。

  const { items: menus, loading } = useQueryList('/menus');

其实主要就是利用 renderFormItem 这个参数。

填充好组件就行。

TreeSelect 是有层级关系的。

在这里插入图片描述

如果不需要

可以用 Select 就没有层级了
类似它:
在这里插入图片描述

 {
      title: '角色',
      width: 150,
      dataIndex: 'roles',
      renderText: (val: {name: string}[]) => val && val.map(role => role.name).join(', '),
      // @ts-ignore
      renderFormItem: (_, {type, defaultRender, formItemProps, fieldProps, ...rest}, form) => {
        if (type === 'form') {
          return null;
        }
        return (
          <Form.Item name="roles">
            <Select
              filterOption={(input, option: any) =>
                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
              }
              showSearch
              options={roles.map((role: any) => ({
                label: role.name,
                value: role.id
              }))}
              allowClear
              placeholder="请选择角色"
            />
          </Form.Item>
        );
        return defaultRender(_);
      }
    },

请求参数

这里值得注意的是要关注它的请求参数

在这里插入图片描述
点击查询之后,请求参数是这样的:

传的是 父级的 _id

后端

参数是怎样的,无所谓,只要对了,只要能传 _id 就行。

后端只需要取到值即可

const buildQuery = (queryParams: any): any => {
  const query: any = {};

  if (queryParams.name) {
    query.name = { $regex: queryParams.name, $options: 'i' };
  }

  if (queryParams.path) {
    query.path = { $regex: queryParams.path, $options: 'i' };
  }

  if (queryParams.parent) {
    try {
      query.parent = JSON.parse(queryParams.parent).name;
    } catch (error) {
      console.error('Failed to parse parent JSON:', error);
      query.parent = null;
    }
  } else {
    query.parent = null;
  }

  // Add recursive children query
  if (queryParams.children) {
    query.children = [
      { 'children.name': { $regex: queryParams.children, $options: 'i' } },
      // Add conditions for other child properties if needed
    ];
  }

  return query;
};

主要还是这里:

  if (queryParams.parent) {
    try {
      query.parent = JSON.parse(queryParams.parent).name;
    } catch (error) {
      console.error('Failed to parse parent JSON:', error);
      query.parent = null;
    }
  } else {
    query.parent = null;
  }

其实那个 name 就是 _id ,查一下即可

model 是这样的:

const menuSchema = new mongoose.Schema(
  {
    name: { type: String, required: true },
    path: { type: String, required: true },
    parent: { type: mongoose.Schema.Types.ObjectId, ref: 'Menu' },
    permission: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Permission',
      required: true,
    },
  },
  { timestamps: true },
);

完结。

获取 ant design pro & nodejs & typescript 多角色权限动态菜单管理系统源码
我正在做的程序员赚钱副业 - Shopify 真实案例技术赚钱营销课视频教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值