antd 树型控件默认选中数据来自于接口(接口采用的是ahooks),当初始化时接口没有请求到数据,此时是undefined,树型控件初始化就无法默认选中(数据是前端写死的,使用里面的默认展开,默认选中事件,直接调用文档的API即可,如果数据是从后端获取的,那么就需要作一些改动) antd跟默认相关的前缀有default的都只是第一次有用,第二次就没用了。
方法一
import {Button, Form, notification, Space, Tree} from 'antd';
import {PageContainer} from '@ant-design/pro-layout';
import {history} from '@@/core/history';
import {get_menu_data_roleId, get_role_menu, post_add_menu} from '@/services/SystemSettings';
import {useRequest} from 'ahooks';
import {useEffect, useImperativeHandle, useMemo, useRef, useState} from "react";
const Index = () => {
/**子组件的实例属性输出到父组件**/
const ref1 = useRef<any>(null);
/**tree树形源数据**/
const [SalesData, setSalesData] = useState<any[]>([]);
/**菜单回显接口**/
const FetchData = useRequest(
() => {
return get_menu_data_roleId({
roleId: history.location?.query?.roleId,
});
},
{},
);
/**销售管理定义树形结构可展开**/
const [expandedKeys, setExpandedKeys] = useState(['1550382838808662018']);
/**销售管理树形定义**/
const SalesTree = (props: any) => {
const {treeData, chooseKey, getDataRef} = props;
const [_choosekeys, _setChooseKeys] = useState<React.Key[]>([]);
/**可展开处理**/
const onExpand = (expandedKeysValue: any) => {
console.log('onExpand', expandedKeysValue);
const deepCopyKeys = Object.assign([], expandedKeysValue);
setExpandedKeys(deepCopyKeys);
};
/**计算缓存**/
const _childKeys = useMemo(() => {
const handleKeys = (trees: any): string[] => {
let arr: string[] = [];
for (let i = 0; i < trees.length; i++) {
const _child = trees[i].children;
if (!_child || _child?.length === 0) {
arr.push(trees[i].key + '');
} else {
if (!!_child) {
const keys = handleKeys(_child);
arr = [...arr, ...keys];
}
}
}
return arr;
};
if (!chooseKey || !treeData) {
return [];
}
return handleKeys(treeData);
}, [treeData, chooseKey]);
//子组件返回给父组件自身的状态和方法ref
useImperativeHandle(getDataRef, () => {
return {
getChooseKey: () => {
const getChoosekeysParents = (_keys: React.Key[]) => {
let _arr: any[] = [];
const loopArr = (trees: any[], parentsKeys: any[] = []) => {
console.log(parentsKeys, 'parentsKeys');
for (let i = 0; i < trees.length; i++) {
const _child = trees[i].children;
const _item = trees[i].key;
console.log(_item, '_item');
if (_child && _child.length > 0) {
loopArr(_child, [...parentsKeys, _item]);
} else {
if (_keys.includes(_item)) {
_arr = [..._arr, ...parentsKeys];
}
}
}
};
if (treeData) {
loopArr(treeData);
}
return Array.from(new Set(_arr));
};
const childrenKeys = _childKeys.filter((_item) => _choosekeys.includes(_item));
const parentsKeys = getChoosekeysParents(childrenKeys);
return Array.from(new Set([...childrenKeys, ...parentsKeys])) as any;
},
};
});
useEffect(() => {
if (chooseKey && treeData) {
_setChooseKeys(() => {
return _childKeys.filter((_item) => chooseKey.includes(_item));
});
}
}, [chooseKey, treeData, _childKeys]);
return (
<>
<Tree
checkable
expandedKeys={expandedKeys}
onExpand={onExpand}
treeData={treeData}
checkedKeys={_choosekeys}
onCheck={(checkedKeysValue) => {
if (checkedKeysValue instanceof Array) {
_setChooseKeys(checkedKeysValue);
}
}}
/>
</>
);
};
return (
<>
<Tree
checkable
expandedKeys={InventoryexpandedKeys}
onExpand={onExpand}
treeData={treeData}
checkedKeys={_choosekeys}
onCheck={(checkedKeysValue) => {
if (checkedKeysValue instanceof Array) {
_setChooseKeys(checkedKeysValue);
}
}}
/>
</>
);
};
/*接口*菜单树源数据**/
useRequest(
() => {
return get_role_menu({});
},
{
onSuccess: (res: any) => {
[res.data?.at(0)].forEach((item: any) => {
item.key = item.id;
item.title = item.name;
item.children.forEach((_item: any) => {
_item.key = _item.id;
_item.title = _item.name;
})
});
setSalesData([res.data?.at(0)]);
},
},
);
/*接口*新增_编辑菜单**/
const AddMenu = useRequest(
() => {
const _value: any = [];
const idList1 = ref1.current?.getChooseKey() || [];
_value.push(idList1)
/**处理选择数据数组合并**/
const menuListId = _value.flat()
.filter((item: any) => {
return item != undefined;
});
return post_add_menu({
menuIdList: menuListId || [],
roleId: history.location?.query?.roleId,
});
},
{
manual: true,
onSuccess: () => {
notification.success({
message: '新增/编辑菜单权限成功',
});
history.push('/SystemSettings/RolePermissions');
},
onError: () => {
notification.error({
message: '新增/编辑菜单权限失败',
});
},
},
);
return (
<>
<PageContainer>
<Button
htmlType={'submit'}
type="primary"
onClick={() => {
AddMenu.run();
}}
>
保存
</Button>
<div className={style.border}/>
<div style={{margin: 10}}>
<div className={style.table}>
<div className={style.tree_one}>
//引用定义tree组件
<SalesTree treeData={SalesData} chooseKey={FetchData.data?.data} getDataRef={ref1}/>
</div>
</div>
</PageContainer>
</>
);
};
export default Index;
方法二
import style from './Welcome.less'
import {SettingFilled} from "@ant-design/icons";
import {Modal, notification, Space, Tag, Tree} from "antd";
import React, {useEffect, useState} from "react";
import {useRequest} from "ahooks";
import {get_menu_data, get_user_data, get_user_menu, post_addmenu} from "@/services/SystemSettings";
import {history} from "@@/core/history";
const Index = () => {
const [visible, setVisible] = useState(false);
/**tree树型常用菜单树定义**/
const [Institutions, setInstitutions] = useState<any>();
const [expandedKeys, setExpandedKeys] = useState(['1550382838808662017']);
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>();
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [AddMenu, setAddMenu] = useState<any>();
const [loading, setLoading] = useState<boolean>(true);
const [Trigger, setTrigger] = useState<any>()
/**回显**/
const FetchData = useRequest(() => {
return get_menu_data({});
}, {
onSuccess(res: any) {
setTrigger(res.data);
}
});
useEffect(() => {
if (Trigger instanceof Array) {
setLoading(false);
setCheckedKeys(Trigger)
}
}, [Trigger])
/**树形菜单接口**/
useRequest(get_user_data, {
onSuccess: (res) => {
res.data.forEach((item: any) => {
item.title = item.name;
item.key = item.id;
item.children.forEach((_item: any) => {
_item.key = _item.id;
_item.title = _item.name;
})
});
const tree = [
{
title: '菜单',
key: '1550382838808662017',
children: res.data,
},
];
setInstitutions(tree);
},
});
/**设置常用菜单**/
const addTree = useRequest(() => {
if (AddMenu) {
const isAdd = AddMenu.length >= 14 ? notification.success({message: '常用菜单选择请小于10个!!!'}) : AddMenu || []
return post_addmenu(isAdd || []);
} else {
return post_addmenu([]);
}
}, {
manual: true,
onSuccess: () => {
notification.success({
message: '设置菜单成功!'
});
history.push('/');
},
onError: () => {
notification.error({
message: '设置菜单失败,请检查!'
})
}
});
/**树形**/
const TreeMenu = () => {
//++++**可展开处理**++++++
const onExpand = (expandedKeysValue: any) => {
console.log('onExpand', expandedKeysValue);
const deepCopyKeys = Object.assign([], expandedKeysValue);
setExpandedKeys(deepCopyKeys);
};
const onCheck = (checkedKeysValue: any, checkedNodes: any) => {
setAddMenu(checkedKeysValue.concat(checkedNodes.halfCheckedKeys));
setCheckedKeys(checkedKeysValue);
};
const onSelect = (selectedKeysValue: React.Key[], info: any) => {
console.log('onSelect', info);
setSelectedKeys(selectedKeysValue);
};
return <div>
{loading ? null : <Tree
height={300}
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={Institutions}
/>}
</div>
};
return <>
<div className={'container'}>
<div className={style.style_top}>常用功能</div>
<div>
<SettingFilled style={{fontSize: 24}} onClick={() => {
setVisible(true);
FetchData.run();
}}/>
<Modal
title="常用菜单设置"
centered
visible={visible}
onOk={() => {
setVisible(false);
addTree.run();
}}
onCancel={() => setVisible(false)}
>
<TreeMenu/>
</Modal>
</div>
</div>
</>
}
export default Index;