龙空技术网

antd Cascader(或TreeSelec )仅根据最后一级value回显完整路径

锅巴瓜子 81

前言:

如今朋友们对“前端回显”大概比较着重,朋友们都想要学习一些“前端回显”的相关知识。那么小编也在网络上网罗了一些对于“前端回显””的相关文章,希望各位老铁们能喜欢,姐妹们快快来学习一下吧!

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时如何获得父节点信息?

其思路就是将节点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树选择器,我就不具体写了哦。

标签: #前端回显