8

antd 级联选择器Cascader(或TreeSelect树选择器 )如何仅根据最后一级value回显完整...

 1 year ago
source link: https://www.daozhao.com/10769.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

antd 级联选择器Cascader(或TreeSelect树选择器 )如何仅根据最后一级value回显完整中文路径

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

antd 级联选择器Cascader(或TreeSelect树选择器 )如何仅根据最后一级value回显完整中文路径

Cascader(或TreeSelect树选择器 )往往会在项目中用在分类管理这一需求,可以很好的展示分类的层级结构,有时可能因为分类会存在改变层级(如由四级分类变成了二级分类)的情况,后端接口会要求在存储分类数据的时候,仅传递最后一级的信息。

举个antd官网的例子:

import { Cascader } from 'antd';

const options = [
  {
    value: 'zhejiang',
    label: 'Zhejiang',
    children: [
      {
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [
          {
            value: 'xihu',
            label: 'West Lake',
          },
        ],
      },
    ],
  },
  {
    value: 'jiangsu',
    label: 'Jiangsu',
    disabled: true,
    children: [
      {
        value: 'nanjing',
        label: 'Nanjing',
        children: [
          {
            value: 'zhonghuamen',
            label: 'Zhong Hua Men',
          },
        ],
      },
    ],
  },
];

function onChange(value) {
  console.log(value);
}

ReactDOM.render(<Cascader options={options} onChange={onChange} />, mountNode);

在选中Zhejiang / Hangzhou / Wes tLake时,对应的value是['zhejiang', 'hangzhou', 'xihu'],后端可能只需要你传递xihu即可,而非数组形式的网站路径信息。

这时前端在回显的时候会出现一个问题,无法根据xihu完整的回显之前的路径名Zhejiang / Hangzhou / Wes tLake了。

如何收集完整的节点路径信息

我们可以借助官网在TreeSelect给的提示onChange时如何获得父节点信息?

file

其思路就是将节点value作为对象valueMap的key,遍历节点的子节点children(如果有的话),通过parent该节点和其子节点链接起来。后续就可以用getPath方法根据valuevalueMap通过parent一层一层找到对应的父节点信息了。

const valueMap = {};
function loops(list, parent) {
  return (list || []).map(({ children, value, label }) => {
    const node = (valueMap[value] = {
      parent,
      data: {
        label,
        value
      }
    });
    node.children = loops(children, node);
    return node;
  });
}

loops(treeData);

function getPath(value, prop) {
  const path = [];
  let current = valueMap[value];
  while (current) {
    path.unshift(current.data[prop]);
    current = current.parent;
  }
  return path;
}

简单改造下,同时valueMap同时收集下lable信息,同时getPath支持返回指定prop的信息,让回显更加灵活。

如何使用getPath完成数据

方法一:我们可以直接通过ref暴露出去
useImperativeHandle(ref, () => ({
valueMap,
getPath,
}))

但是这样在部分使用起来不合适,比如列表展示时,并且这样也会存在因为列表数据渲染时`Cascader`的`valueMap`还未收集好,而`getPath`获取结果为空的情况。

我们可以试试方法二

方法二:支持自定义render
function CategorySelect(props, ref) {
  const [value, setValue] = useState([]);
  const [valueMap, setValueMap] = useState({});
  // 根据value回显对应的label
  const fullLabelPath = useMemo(() => {
    if (!props.displayLabel) {
      return;
    }
    return getPath(props.value, props.displayLabel);
  }, [props.displayLabel, props.value, props.data, valueMap]);

  ...

  return {
    (props.fullLabelRender)
      ? props.fullLabelRender(fullLabelPath)
      : (
          
        )
  }
}

我们将全路径的渲染能力开放通过`props.fullLabelRender`

使用可以这样使用

fullLabelRender={(fullLabelPath) => ({ fullLabelPath.join(' / ') })}

因为fullLabelPathuseMemo的返回值,valueMapuseState的返回值,这样我们也不必担心列表数据渲染时Cascader的valueMap还未收集好的情况了,待valueMap收集完毕后,自会重新渲染的。

同样的思路也可以用在TreeSelect树选择器,我就不具体写了哦。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK