perf: 优化TreeSelectPanel组件

This commit is contained in:
dap 2024-09-26 08:06:47 +08:00
parent e5ba0a2f31
commit 0112514339
2 changed files with 40 additions and 22 deletions

View File

@ -9,6 +9,7 @@ import { findGroupParentIds, treeToList } from '@vben/utils';
import { Checkbox, Tree } from 'ant-design-vue';
/** 需要禁止透传 */
defineOptions({ inheritAttrs: false });
const props = defineProps({
@ -24,6 +25,11 @@ const props = defineProps({
default: () => ({ key: 'id', title: 'label' }),
type: Object as PropType<{ key: string; title: string }>,
},
/** 点击节点关联/独立时 清空已勾选的节点 */
resetOnStrictlyChange: {
default: true,
type: Boolean,
},
treeData: {
default: () => [],
type: Array as PropType<DataNode[]>,
@ -43,10 +49,6 @@ const innerCheckedStrictly = computed(() => {
return !props.checkStrictly;
});
function handleCheckStrictlyChange(e: CheckboxChangeEvent) {
emit('checkStrictlyChange', e.target.checked);
}
const associationText = computed(() => {
return props.checkStrictly ? '父子节点关联' : '父子节点独立';
});
@ -61,11 +63,11 @@ const checkedKeys = defineModel('value', {
});
// ID
const allKeys = computed(() => {
const id = props.fieldNames.key;
return treeToList(props.treeData).map((item: any) => item[id]);
const idField = props.fieldNames.key;
return treeToList(props.treeData).map((item: any) => item[idField]);
});
/** 已经选择的所有节点 包括子/父节点 */
/** 已经选择的所有节点 包括子/父节点 用于提交 */
const checkedRealKeys = ref<(number | string)[]>([]);
/**
@ -122,30 +124,46 @@ function handleExpandOrCollapseAll(e: CheckboxChangeEvent) {
expandedKeys.value = expand ? allKeys.value : [];
}
function handleCheckStrictlyChange(e: CheckboxChangeEvent) {
emit('checkStrictlyChange', e.target.checked);
if (props.resetOnStrictlyChange) {
checkedKeys.value = [];
checkedRealKeys.value = [];
}
}
/**
* 暴露方法来获取用于提交的全部节点
*/
defineExpose({
getCheckedKeys: () => checkedRealKeys.value,
});
onMounted(() => {
onMounted(async () => {
if (props.expandAllOnInit) {
nextTick(() => {
await nextTick();
expandedKeys.value = allKeys.value;
});
}
});
</script>
<template>
<div class="bg-background w-full rounded-lg border-[1px] p-[12px]">
<div class="flex items-center gap-2 border-b-[1px] pb-2">
<div class="flex items-center justify-between gap-2 border-b-[1px] pb-2">
<div>
<span>节点状态: </span>
<span
:class="[props.checkStrictly ? 'text-primary' : 'text-red-500']"
class="font-semibold"
>
<span :class="[props.checkStrictly ? 'text-primary' : 'text-red-500']">
{{ associationText }}
</span>
</div>
<div>
已选中
<span class="text-primary mx-1 font-semibold">
{{ checkedRealKeys.length }}
</span>
个节点
</div>
</div>
<div
class="flex flex-wrap items-center justify-between border-b-[1px] py-2"
>

View File

@ -8,9 +8,9 @@ import { cloneDeep } from '@vben/utils';
import { useVbenForm } from '#/adapter';
import { menuTreeSelect, roleMenuTreeSelect } from '#/api/system/menu';
import { roleAdd, roleInfo, roleUpdate } from '#/api/system/role';
import { TreeSelectPanel } from '#/components/tree';
import { drawerSchema } from './data';
import MenuSelect from './menu-select.vue';
const emit = defineEmits<{ reload: [] }>();
@ -115,11 +115,11 @@ function handleMenuCheckStrictlyChange(value: boolean) {
<BasicForm>
<template #menuIds="slotProps">
<!-- check-strictly为readonly 不能通过v-model绑定 -->
<MenuSelect
<TreeSelectPanel
ref="menuSelectRef"
v-bind="slotProps"
:check-strictly="formApi.form.values.menuCheckStrictly"
:menu-tree="menuTree"
:tree-data="menuTree"
@check-strictly-change="handleMenuCheckStrictlyChange"
/>
</template>