From 2ce3786ee00a3c529e980e06bdfa6bd379d635ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 17 Apr 2026 12:17:43 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E6=A0=91=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TreePanel/index.vue | 62 +++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/components/TreePanel/index.vue b/src/components/TreePanel/index.vue index 0861dbb..f3fdf12 100644 --- a/src/components/TreePanel/index.vue +++ b/src/components/TreePanel/index.vue @@ -24,13 +24,22 @@ class="mt-2 dept-tree" :node-key="nodeKey" :data="data" - :props="treeProps as any" + :props="mergedTreeProps as any" :expand-on-click-node="false" :filter-node-method="internalFilterNode" highlight-current default-expand-all @node-click="onNodeClick" - /> + > + + @@ -49,6 +58,8 @@ const props = withDefaults( nodeKey?: string; /** el-tree props 配置 */ treeProps?: Record; + /** 节点禁用字段名,未提供或字段不存在则忽略 */ + disabledField?: string; /** 展开时占的栅格列数 (lg) */ expandedSpan?: number; /** 默认过滤字段名 (用于内置 filterNode) */ @@ -62,6 +73,7 @@ const props = withDefaults( placeholder: '请输入名称', nodeKey: 'id', treeProps: () => ({ label: 'label', children: 'children' }), + disabledField: 'disabled', expandedSpan: 5, filterField: 'label', collapsed: false @@ -81,6 +93,28 @@ const modelCollapsed = computed({ const filterText = ref(''); const treeRef = ref(); +const mergedTreeProps = computed(() => { + if (!props.disabledField) { + return props.treeProps; + } + return { + ...props.treeProps, + disabled: props.treeProps?.disabled ?? props.disabledField + }; +}); + +const getNodeLabel = (data: any) => { + const labelField = props.treeProps?.label ?? 'label'; + return data?.[labelField] ?? ''; +}; + +const isNodeDisabled = (data: any) => { + if (!props.disabledField) { + return false; + } + return Boolean(data?.[props.disabledField]); +}; + const toggleCollapsed = () => { modelCollapsed.value = !modelCollapsed.value; }; @@ -101,6 +135,10 @@ watchEffect( ); const onNodeClick = (data: any, node: any, component: any) => { + if (isNodeDisabled(data)) { + treeRef.value?.setCurrentKey(undefined); + return; + } emit('node-click', data, node, component); }; @@ -211,6 +249,26 @@ $mobile-breakpoint: 900px; background: transparent; } +.tree-panel-shell :deep(.tree-node-label) { + display: inline-flex; + align-items: center; + gap: 6px; + min-width: 0; + line-height: 22px; + color: var(--el-text-color-primary); +} + +.tree-panel-shell :deep(.tree-node-label.is-disabled) { + color: var(--el-color-danger); +} + +.tree-panel-shell :deep(.tree-node-disabled-icon) { + flex: 0 0 auto; + margin-top: 1px; + font-size: 14px; + color: var(--el-color-danger); +} + @media (max-width: $mobile-breakpoint) { .tree-panel-col { max-width: 100%;