antd 级联选择器Cascader(或TreeSelect树选择器 )如何仅根据最后一级value回显完整...
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.
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时如何获得父节点信息?
其思路就是将节点value作为对象valueMap
的key,遍历节点的子节点children(如果有的话),通过parent该节点和其子节点链接起来。后续就可以用getPath
方法根据value
在valueMap
通过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(' / ') })}
因为fullLabelPath
是useMemo
的返回值,valueMap
是useState
的返回值,这样我们也不必担心列表数据渲染时Cascader的valueMap
还未收集好的情况了,待valueMap
收集完毕后,自会重新渲染的。
同样的思路也可以用在TreeSelect树选择器,我就不具体写了哦。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK