前端实现具有依赖关系的多个级联选择器

背景

  • 使用的antd-design级联选择器[Cascader](https://ant-design.antgroup.com/components/cascader-cn)
  • 根据数据映射出级联选择器,但是有的级联选择器要看她的依赖值有没有被选择,选择后才会显示

比如没选择前:

选择后显示:

方案

js 复制代码
      group_code: "A", // 树选择框的code
      group_desc: "测试A", // 树选择框的中文
      placeholder: "测试A", // 树选择框的提示
      dependencse: [], // 树选择框的依赖性决定是否要现实
      group_options: [ //树选择框的具体值
        { //antd design常用结构
          label: "A1", 
          value: "A1",
          children: [],
        },
      ],
    },

1. 导入依赖

javascript 复制代码
import { useState } from "react";
import { Cascader } from "antd";
  • useState 是 React 的一个 Hook,用于在函数组件中管理状态。
  • Cascader 是 Ant Design 提供的级联选择器组件,支持多级联动选择。

2. 组件定义

javascript 复制代码
const MultipleCascader = ({
  multipleCascaderOption,
  selectValues,
  setSelectValues,
}) => {
  • MultipleCascader 是一个函数组件,接收三个 props:
    • multipleCascaderOption:包含级联选择器的配置选项。
    • selectValues:当前已选中的值。
    • setSelectValues:用于更新已选中值的函数。

3. 解构 props

javascript 复制代码
const {
  group_options: options,
  placeholder,
  group_desc,
  group_code,
  dependencse,
} = multipleCascaderOption;
  • multipleCascaderOption 中解构出以下属性:
    • options:级联选择器的选项数据。
    • placeholder:选择器的占位符文本。
    • group_desc:组的描述信息。
    • group_code:组的唯一标识符。
    • dependencse:依赖关系,表示当前选择器是否依赖于其他选择器的选择结果。

4. 状态管理

javascript 复制代码
const [value, setValue] = useState();
  • value 用于存储当前选择器的选中值。
  • setValue 是更新 value 的函数。

5. handleDisabled 函数

javascript 复制代码
const handleDisabled = (extraLogic) => {
  const values = selectValues.filter(
    (option) => option.group_code !== group_code
  );

  values
    .filter((option) =>
      option.dependencse.some((opt) => opt.startsWith(group_code))
    )
    .forEach((option) =>
      extraLogic ? (option.is_disabled = extraLogic(option)) : true
    );
  return values;
};
  • 该函数用于处理依赖关系,禁用或启用其他选择器。
  • extraLogic 是一个可选的回调函数,用于自定义禁用逻辑。
  • 首先过滤掉当前选择器的值,然后根据依赖关系禁用或启用其他选择器。

6. onChange 函数

javascript 复制代码
const onChange = (selectRows, selectedOptions) => {
  let rows = selectRows,
    values;
  if (selectRows.length === 0) {
    values = handleDisabled();
  } else {
    const group = selectRows[selectRows.length - 1][0];
    rows = selectRows.filter((item) => item[0] === group);
    const secondLevelMenus = selectRows.map((item) => item[1]);
    const children = selectedOptions[selectedOptions.length - 1][0].children;
    const value = rows[0][0];
    const key = `${group_code}-${value}`;
    const sameValue = selectValues.find((option) => option.key === key);

    values = [
      ...handleDisabled((option) => !option.dependencse.includes(key)),
      {
        ...sameValue,
        key,
        group_code,
        group_desc,
        value,
        reasons: children.filter(({ value }) =>
          secondLevelMenus.includes(String(value))
        ),
        dependencse,
        is_disabled: false,
      },
    ];
  }
  setValue(rows);
  setSelectValues(values);
};
  • 该函数在用户选择选项时触发。
  • 根据用户的选择更新 valueselectValues
  • 如果用户清空了选择,调用 handleDisabled 函数处理依赖关系。
  • 如果用户选择了选项,更新 selectValues 并处理依赖关系。

7. showCascader 函数

javascript 复制代码
const showCascader = () => {
  if (dependencse.length === 0) {
    return true;
  }
  return dependencse.some((option) =>
    selectValues.some(({ key }) => key === option)
  );
};
  • 该函数用于判断是否显示当前级联选择器。
  • 如果没有依赖关系(dependent 为空),则显示选择器。
  • 如果有依赖关系,则检查依赖的选择器是否有选中值,如果有则显示当前选择器。

8. 渲染逻辑

javascript 复制代码
if (showCascader()) {
  return (
    <Cascader
      multiple
      value={value}
      style={{ minWidth: 140, marginRight: 20 }}
      showCheckedStrategy={Cascader.SHOW_CHILD}
      placeholder={placeholder}
      maxTagCount={1}
      expandTrigger="hover"
      options={options}
      onChange={onChange}
    />
  );
}
return <></>;
  • 根据 showCascader 的返回值决定是否渲染 Cascader 组件。
  • 如果返回 true,则渲染 Cascader 组件,并传入相关属性。
  • 如果返回 false,则返回空片段 <> </>,不渲染任何内容。

测试地址 codesandbox.io/p/sandbox/m...

相关推荐
YGY Webgis糕手之路2 小时前
OpenLayers 综合案例-轨迹回放
前端·经验分享·笔记·vue·web
90后的晨仔3 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
Ares-Wang3 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
90后的晨仔3 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
德育处主任3 小时前
p5.js 正方形square的基础用法
前端·数据可视化·canvas
烛阴3 小时前
Mix - Bilinear Interpolation
前端·webgl
90后的晨仔3 小时前
Vue 3 应用实例详解:从 createApp 到 mount,你真正掌握了吗?
前端·vue.js
德育处主任3 小时前
p5.js 矩形rect绘制教程
前端·数据可视化·canvas
前端工作日常4 小时前
我学习到的babel插件移除Flow 类型注解效果
前端·babel·前端工程化
前端工作日常4 小时前
我学习到的 Babel 配置
前端·babel·前端工程化