@zl-ui-kit/components 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,6 +48,7 @@ ZL UI 业务组件库 —— Element Plus 体系,`Zl` 前缀,47 个业务组
48
48
  - [ZlAction / ZlActionList —— 操作列与操作列表](#zlaction-zlactionlist-操作列与操作列表)
49
49
  - [ZlRadioTag / ZlCheckboxTag / ZlCheckAll / ZlSorter / ZlAddSub / ZlLayoutSwitch](#zlradiotag-zlcheckboxtag-zlcheckall-zlsorter-zladdsub-zllayoutswitch)
50
50
  - [ZlTabs / ZlDynamicComponent / ZlGrid](#zltabs-zldynamiccomponent-zlgrid)
51
+ - [ZlTree —— 树形控件(多选 / 暴露方法)](#zltree-树形控件多选-暴露方法)
51
52
  - [8. 布局与权限](#8-布局与权限)
52
53
  - [ZlAppLayout / ZlAppMenu](#zlapplayout-zlappmenu)
53
54
  - [ZlPermission](#zlpermission)
@@ -892,9 +893,11 @@ const { data: treeData, loading: treeLoading } = treeReq
892
893
  ```
893
894
 
894
895
  ```vue
895
- <ZlTree v-if="!treeLoading" :data="treeData" :props="{ label: 'title', children: 'children' }" />
896
+ <ZlTree v-if="!treeLoading" :data="treeData" disable-filter :field-names="{ key: 'id', title: 'name' }" />
896
897
  ```
897
898
 
899
+ 字段映射用 `fieldNames`(不是 `el-tree` 的 `props`);多选的勾选取值见 §7 › ZlTree。
900
+
898
901
  #### ⑧ `ZlChart` —— `useDataRequest` 解包后构建 option
899
902
 
900
903
  `ZlChart` 显式 prop 为 `series`,其余配置(title/xAxis/yAxis/tooltip/grid)经 attrs 透传,故用 `v-bind` 传完整 echarts option:
@@ -1074,6 +1077,69 @@ const statusActions = (item: Item): ActionItem[] => [
1074
1077
  - `ZlDynamicComponent`:schema→VNode 渲染引擎,默认 `el-input`。
1075
1078
  - `ZlGrid`(+`ZlGridItem`):自绘栅格,label 自适应/跨列/省略提示/字典。
1076
1079
 
1080
+ ### ZlTree —— 树形控件(多选 / 暴露方法)
1081
+
1082
+ `el-tree` 的封装:自带搜索框、节点图标与超长省略,**其余 `el-tree` 属性与事件原样透传**
1083
+ (懒加载 `load` / `lazy`、拖拽 `draggable`、`accordion`、`check-on-click-node`、`@node-click` 等直接写即可)。
1084
+
1085
+ **字段映射**(arco `fieldNames` 兼容,不用再传 `:props`):
1086
+
1087
+ ```vue
1088
+ <ZlTree :data="treeData" :field-names="{ key: 'id', title: 'name', children: 'items', disabled: 'locked' }" />
1089
+ ```
1090
+
1091
+ | 字段 | 作用 |
1092
+ | ---------- | --------------------------------------------------------------------- |
1093
+ | `key` | 节点唯一标识字段(同时作为 `node-key`,勾选 / 展开 / 取值都按它匹配) |
1094
+ | `title` | 显示文本字段(对应 `el-tree` 的 `props.label`) |
1095
+ | `children` | 子级字段 |
1096
+ | `disabled` | 数据里的布尔字段名 → 节点置灰且**不可勾选** |
1097
+ | `isLeaf` | 数据里的布尔字段名 → 强制视为叶子(懒加载判断有没有下一级) |
1098
+
1099
+ > 需要按业务规则动态禁用时直接传 `:props="{ disabled: (data) => xxx }"`:该写法与 `fieldNames`
1100
+ > **合并生效**(只覆盖同名项,`label`/`children` 不丢)。
1101
+
1102
+ **多选(复选框)** —— 取值有两种写法,按需选一种:
1103
+
1104
+ ```vue
1105
+ <!-- ① 受控:勾选态由外部数据管理,提交时直接用 checkedKeys -->
1106
+ <ZlTree
1107
+ v-model:checked-keys="checkedKeys"
1108
+ v-model:half-checked-keys="halfCheckedKeys"
1109
+ show-checkbox
1110
+ :data="treeData"
1111
+ />
1112
+
1113
+ <!-- ② 命令式:只在需要时向实例取值 -->
1114
+ <ZlTree ref="treeRef" show-checkbox check-strictly :data="treeData" />
1115
+ ```
1116
+
1117
+ ```ts
1118
+ // ② 里的取法:leafOnly 只要叶子;includeHalfChecked 连半选一起返回
1119
+ treeRef.value.getCheckedNodes(false, true)
1120
+ treeRef.value.getCheckedKeys(true)
1121
+ ```
1122
+
1123
+ - `check-strictly`:父子不关联,每个节点独立勾选;
1124
+ - `check-descendants`:勾选父节点时联动勾选全部子孙;
1125
+ - 受控 `checked-keys` 由组件写回树,**不要再同时传 `default-checked-keys`**(两份初始值会互相覆盖);
1126
+ 非受控场景用 `el-tree` 原生的 `default-checked-keys` / `default-expanded-keys` 透传即可。
1127
+
1128
+ **暴露方法**(完整逐条说明见 §14 `ZlTree` 的「暴露」表,模板 ref 调用):
1129
+
1130
+ | 场景 | 方法 |
1131
+ | ------ | ------------------------------------------------------------------------------------------------------ |
1132
+ | 勾选 | `getCheckedKeys` / `getCheckedNodes` / `getHalfCheckedKeys` / `getHalfCheckedNodes` / `setChecked` |
1133
+ | 批量 | `setCheckedKeys` / `setAllChecked(true)` 全选 / `clearChecked()` 清空 |
1134
+ | 高亮 | `getCurrentKey` / `getCurrentNode` / `setCurrentKey` / `setCurrentNode` |
1135
+ | 展开 | `expandAll` / `collapseAll` / `filter('关键字')`(与内置搜索框同步) |
1136
+ | 改数据 | `getNode` / `getNodePath` / `updateKeyChildren` / `append` / `insertBefore` / `insertAfter` / `remove` |
1137
+ | 兜底 | `elTree`:内部 `el-tree` 实例,未列出的原生能力从这里取 |
1138
+
1139
+ **自定义节点**:`#title` 只换标题(保留内置图标与省略号)、`#icon` 只换图标、`#default` 接管整个节点
1140
+ (与 `el-tree` 的 `#default` 写法一致,内置图标/省略号会被替掉)。playground `/component/ZlTree` 有
1141
+ 「勾选多选 + 业务禁用 + 全选/清空/展开/收起」的可交互示例。
1142
+
1077
1143
  ---
1078
1144
 
1079
1145
  ## 8. 布局与权限
@@ -3145,7 +3211,7 @@ const { i18n } = useLocale({ messages })
3145
3211
  | [`ZlText`](#zltext) | 主入口 | 1 | 0 | 1 | 0 |
3146
3212
  | [`ZlTitle`](#zltitle) | 主入口 | 5 | 0 | 3 | 0 |
3147
3213
  | [`ZlUpload`](#zlupload) | 主入口 | 13 | 1 | 1 | 0 |
3148
- | [`ZlTree`](#zltree) | 主入口 | 5 | 0 | 3 | 0 |
3214
+ | [`ZlTree`](#zltree) | 主入口 | 10 | 2 | 5 | 23 |
3149
3215
  | [`ZlTreeSelect`](#zltreeselect) | 主入口 | 6 | 1 | 0 | 0 |
3150
3216
  | [`ZlChart`](#zlchart) | 子入口 chart | 2 | 0 | 0 | 1 |
3151
3217
  | [`ZlEditor`](#zleditor) | 子入口 editor | 3 | 1 | 0 | 0 |
@@ -5322,7 +5388,9 @@ import { ZlUpload } from '@zl-ui-kit/components'
5322
5388
 
5323
5389
  <sub>入口 `@zl-ui-kit/components` · 源码 `packages/components/src/components/ZlTree/index.vue`</sub>
5324
5390
 
5325
- **接口概览**:5 props · 3 插槽
5391
+ **简介**:树形控件:内置搜索框、节点图标与超长省略;复选框多选可用 `v-model:checked-keys` 受控, 字段映射走 `fieldNames`(arco 兼容),`el-tree` 其余属性与事件(懒加载 / 拖拽 / `@node-click`)原样透传。
5392
+
5393
+ **接口概览**:10 props · 2 事件 · 5 插槽 · 23 暴露
5326
5394
 
5327
5395
  **用法示例**
5328
5396
 
@@ -5332,11 +5400,17 @@ import { ZlTree } from '@zl-ui-kit/components'
5332
5400
  </script>
5333
5401
 
5334
5402
  <template>
5335
- <ZlTree :data="treeData" :field-names="fieldNames" />
5403
+ <ZlTree
5404
+ :ref="treeInstance"
5405
+ :data="checkableTreeData"
5406
+ :field-names="fieldNames"
5407
+ v-model:checked-keys="value"
5408
+ show-checkbox
5409
+ />
5336
5410
  </template>
5337
5411
  ```
5338
5412
 
5339
- > 示例中的 `data`、`fieldNames` 是数组 / 对象 / 函数等非字面量入参,由调用方提供数据;其余属性写法可直接照搬。
5413
+ > 示例中的 `ref`、`data`、`fieldNames` 是数组 / 对象 / 函数等非字面量入参,由调用方提供数据;其余属性写法可直接照搬。
5340
5414
 
5341
5415
  **插槽用法**
5342
5416
 
@@ -5344,7 +5418,9 @@ import { ZlTree } from '@zl-ui-kit/components'
5344
5418
  <template>
5345
5419
  <ZlTree>
5346
5420
  <template #search-extra>…</template>
5421
+ <template #default="{ node, data }">…</template>
5347
5422
  <template #title="{ node, data }">…</template>
5423
+ <template #icon="{ node, data }">…</template>
5348
5424
  <!-- 动态插槽:名字运行时取自 slot -->
5349
5425
  </ZlTree>
5350
5426
  </template>
@@ -5352,21 +5428,63 @@ import { ZlTree } from '@zl-ui-kit/components'
5352
5428
 
5353
5429
  **props**
5354
5430
 
5355
- | 属性 | 类型 | 默认值 | 必填 | 示例 | 说明 |
5356
- | ------------------ | ----------------------------------------------------- | -------------------------------------------------------------- | ---- | ------------------------------ | ------------------------------------------------------- |
5357
- | `fieldNames` | `{ key?: string; title?: string; children?: string }` | `() => ({ key: 'key', title: 'title', children: 'children' })` | 否 | `:field-names="{}"` | 字段映射(arco fieldNames 兼容:title→label、children) |
5358
- | `inputSearchProps` | `Record<string, any>` | — | 否 | `:input-search-props="{}"` | 搜索框透传(el-input 属性) |
5359
- | `filterTreeNode` | `(value: string, data: any) => boolean` | — | 否 | `:filter-tree-node="() => {}"` | 自定义过滤函数(缺省按 title 包含匹配) |
5360
- | `disableFilter` | `boolean` | — | 否 | `disable-filter` | 关闭搜索框 |
5361
- | `loading` | `boolean` | — | 否 | `loading` | 是否显示树区域加载状态 |
5431
+ | 属性 | 类型 | 默认值 | 必填 | 示例 | 说明 |
5432
+ | ------------------ | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ---- | ----------------------------------- | --------------------------------------------------------------------------------------------- |
5433
+ | `checkedKeys` | `ZlTreeKey[]` | — | 否 | `v-model:checked-keys="value"` | 勾选节点 key 数组(受控:传了就用外部值管理勾选态,勿再传 `default-checked-keys`) |
5434
+ | `halfCheckedKeys` | `ZlTreeKey[]` | — | 否 | `v-model:half-checked-keys="value"` | 半选节点 key 数组(父子联动下“部分子节点被勾选”的父节点,提交时用来判断半选状态) |
5435
+ | `fieldNames` | `{ key?: string; title?: string; children?: string; disabled?: string; isLeaf?: string }` | `() => ({ key: 'key', title: 'title', children: 'children' })` | 否 | `:field-names="{}"` | 字段映射(arco fieldNames 兼容:title→label、children;disabled/isLeaf 填数据里的布尔字段名) |
5436
+ | `inputSearchProps` | `Record<string, any>` | — | 否 | `:input-search-props="{}"` | 搜索框透传(el-input 属性) |
5437
+ | `filterTreeNode` | `(value: string, data: any) => boolean` | — | 否 | `:filter-tree-node="() => {}"` | 自定义过滤函数(缺省按 title 包含匹配) |
5438
+ | `disableFilter` | `boolean` | — | 否 | `disable-filter` | 关闭搜索框 |
5439
+ | `loading` | `boolean` | — | 否 | `loading` | 是否显示树区域加载状态 |
5440
+ | `showCheckbox` | `boolean` | `false` | 否 | `show-checkbox` | 显示复选框(多选),取值可用 `v-model:checked-keys` 或 `getCheckedKeys()` |
5441
+ | `checkStrictly` | `boolean` | `false` | 否 | `check-strictly` | 勾选时父子不关联(每个节点独立勾选) |
5442
+ | `checkDescendants` | `boolean` | `false` | 否 | `check-descendants` | 勾选父节点时联动勾选全部子孙(懒加载未展开的层级需要展开后才纳入) |
5443
+
5444
+ **事件(emits)**
5445
+
5446
+ | 事件 | 参数 | 说明 |
5447
+ | ------------------------ | ------------- | -------------- |
5448
+ | `update:checkedKeys` | `ZlTreeKey[]` | `v-model` 更新 |
5449
+ | `update:halfCheckedKeys` | `ZlTreeKey[]` | `v-model` 更新 |
5362
5450
 
5363
5451
  **插槽(slots)**
5364
5452
 
5365
- | 插槽 | 作用域参数 | 示例 | 说明 |
5366
- | -------------- | ------------------------------ | ------------------------------------------------ | -------------------------------------------- |
5367
- | `search-extra` | — | `<template #search-extra>…</template>` | 搜索框右侧附加内容 |
5368
- | `title` | `v-bind="{ node, data }"` 展开 | `<template #title="{ node, data }">…</template>` | 自定义节点标题,参数为 node 和 data |
5369
- | `[slot]` | `v-bind="scope"` 展开 | `<template #[slot]="scope">…</template>` | 按自定义插槽列表生成名称,参数为树插槽上下文 |
5453
+ | 插槽 | 作用域参数 | 示例 | 说明 |
5454
+ | -------------- | ------------------------------ | -------------------------------------------------- | --------------------------------------------------------------------- |
5455
+ | `search-extra` | — | `<template #search-extra>…</template>` | 搜索框右侧附加内容 |
5456
+ | `default` | `node` / `data` | `<template #default="{ node, data }">…</template>` | 自定义整个节点内容(同 el-tree 的 #default,会替掉内置图标与省略号) |
5457
+ | `title` | `v-bind="{ node, data }"` 展开 | `<template #title="{ node, data }">…</template>` | 自定义节点标题,参数为 node 和 data |
5458
+ | `icon` | `v-bind="{ node, data }"` 展开 | `<template #icon="{ node, data }">…</template>` | 自定义节点图标(叶子/分支默认用 zl:document-color / zl:folder-color) |
5459
+ | `[slot]` | `v-bind="scope"` 展开 | `<template #[slot]="scope">…</template>` | 按自定义插槽列表生成名称,参数为树插槽上下文 |
5460
+
5461
+ **暴露(defineExpose)**
5462
+
5463
+ | 名称 | 说明 |
5464
+ | --------------------- | --------------------------------------------------------------------------------------- |
5465
+ | `elTree` | 内部 `el-tree` 实例:下面未列出的原生能力(`store` 等)从这里取 |
5466
+ | `getCheckedKeys` | 勾选节点的 key 数组;`getCheckedKeys(true)` 只取叶子节点 |
5467
+ | `getCheckedNodes` | 勾选节点的数据数组;`leafOnly` 只要叶子,`includeHalfChecked` 连半选节点一起返回 |
5468
+ | `getHalfCheckedKeys` | 半选节点的 key 数组(父子联动下部分勾选的父节点) |
5469
+ | `getHalfCheckedNodes` | 半选节点的数据数组 |
5470
+ | `setCheckedKeys` | 按 key 数组设置勾选;`leafOnly` 表示这些 key 只对应叶子节点(父节点由联动推导) |
5471
+ | `setChecked` | 设置单个节点勾选态:`data` 传 key 或节点数据,`deep=false` 表示不联动父子 |
5472
+ | `setAllChecked` | 全选 / 取消全选(跳过 `props.disabled` 命中的节点;懒加载未展开层级需先 `expandAll()`) |
5473
+ | `clearChecked` | 清空所有勾选与半选 |
5474
+ | `getCurrentKey` | 当前高亮(选中)节点的 key,无选中返回 `null` |
5475
+ | `getCurrentNode` | 当前高亮节点的数据,无选中返回 `null` |
5476
+ | `setCurrentKey` | 设置高亮节点:传 `null` 取消高亮,`expandParent` 是否自动展开父级 |
5477
+ | `setCurrentNode` | 按节点实例设置高亮 |
5478
+ | `filter` | 按值过滤节点(配合 `filterTreeNode`;传空串恢复全量显示) |
5479
+ | `expandAll` | 展开全部已加载节点 |
5480
+ | `collapseAll` | 收起全部节点 |
5481
+ | `getNode` | 取节点实例(可读 `node.checked` / `node.expanded` / `node.level` 等内部状态) |
5482
+ | `getNodePath` | 取从根到该节点的完整路径数据(面包屑、级联回显用) |
5483
+ | `updateKeyChildren` | 按 key 替换子节点数据(懒加载接口回来后刷新某一支) |
5484
+ | `append` | 在父节点下追加子节点:`parentData` 传 key / 数据 / 节点实例,缺省追加到根 |
5485
+ | `insertBefore` | 在参考节点之前插入兄弟节点 |
5486
+ | `insertAfter` | 在参考节点之后插入兄弟节点 |
5487
+ | `remove` | 删除节点(传 key 或节点数据) |
5370
5488
 
5371
5489
  #### `ZlTreeSelect`
5372
5490
 
@@ -5736,7 +5854,7 @@ ZlGrid 子项 schema
5736
5854
  | `el-button`(操作栏 / 卡片内) | `ZlAction` | 操作列与卡片按钮;页面级独立按钮仍可用 `el-button` |
5737
5855
  | `el-tooltip`(超长省略) | `ZlAutoTooltip` | 文字溢出时自动提示 |
5738
5856
  | `el-icon` | `ZlIcon` | 需先注册图标集(§4.1) |
5739
- | `el-tree` | `ZlTree` | |
5857
+ | `el-tree` | `ZlTree` | 勾选多选 / 字段映射 / 暴露方法见 §7 › ZlTree |
5740
5858
  | `el-upload` | `ZlUpload` | |
5741
5859
  | `el-tag` | `ZlTag` | |
5742
5860
  | `el-tabs` | `ZlTabs` | |
@@ -1,9 +1,15 @@
1
+ /** 节点键值类型(即 `node-key` 指向字段的值) */
2
+ type ZlTreeKey = string | number;
3
+ /** 节点原始数据 */
4
+ type ZlTreeData = Record<string, any>;
1
5
  type __VLS_Props = {
2
- /** 字段映射(arco fieldNames 兼容:title→label、children) */
6
+ /** 字段映射(arco fieldNames 兼容:title→label、children;disabled/isLeaf 填数据里的布尔字段名) */
3
7
  fieldNames?: {
4
8
  key?: string;
5
9
  title?: string;
6
10
  children?: string;
11
+ disabled?: string;
12
+ isLeaf?: string;
7
13
  };
8
14
  /** 搜索框透传(el-input 属性) */
9
15
  inputSearchProps?: Record<string, any>;
@@ -13,15 +19,33 @@ type __VLS_Props = {
13
19
  disableFilter?: boolean;
14
20
  /** 是否显示树区域加载状态 */
15
21
  loading?: boolean;
22
+ /** 显示复选框(多选),取值可用 `v-model:checked-keys` 或 `getCheckedKeys()` */
23
+ showCheckbox?: boolean;
24
+ /** 勾选时父子不关联(每个节点独立勾选) */
25
+ checkStrictly?: boolean;
26
+ /** 勾选父节点时联动勾选全部子孙(懒加载未展开的层级需要展开后才纳入) */
27
+ checkDescendants?: boolean;
16
28
  };
29
+ type __VLS_PublicProps = {
30
+ 'checkedKeys'?: ZlTreeKey[];
31
+ 'halfCheckedKeys'?: ZlTreeKey[];
32
+ } & __VLS_Props;
17
33
  declare function __VLS_template(): {
18
34
  attrs: Partial<{}>;
19
35
  slots: Partial<Record<string, (_: any) => any>> & {
20
36
  'search-extra'?(_: {}): any;
37
+ default?(_: {
38
+ node: any;
39
+ data: any;
40
+ }): any;
21
41
  title?(_: {
22
42
  node: any;
23
43
  data: any;
24
44
  }): any;
45
+ icon?(_: {
46
+ node: any;
47
+ data: any;
48
+ }): any;
25
49
  };
26
50
  refs: {
27
51
  treeRef: unknown;
@@ -29,12 +53,69 @@ declare function __VLS_template(): {
29
53
  rootEl: any;
30
54
  };
31
55
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
32
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
56
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_PublicProps, {
57
+ elTree: any;
58
+ /** 勾选节点的 key 数组;`getCheckedKeys(true)` 只取叶子节点 */
59
+ getCheckedKeys: (leafOnly?: boolean) => ZlTreeKey[];
60
+ /** 勾选节点的数据数组;`leafOnly` 只要叶子,`includeHalfChecked` 连半选节点一起返回 */
61
+ getCheckedNodes: (leafOnly?: boolean, includeHalfChecked?: boolean) => ZlTreeData[];
62
+ /** 半选节点的 key 数组(父子联动下部分勾选的父节点) */
63
+ getHalfCheckedKeys: () => ZlTreeKey[];
64
+ /** 半选节点的数据数组 */
65
+ getHalfCheckedNodes: () => ZlTreeData[];
66
+ /** 按 key 数组设置勾选;`leafOnly` 表示这些 key 只对应叶子节点(父节点由联动推导) */
67
+ setCheckedKeys: (keys: ZlTreeKey[], leafOnly?: boolean) => void;
68
+ /** 设置单个节点勾选态:`data` 传 key 或节点数据,`deep=false` 表示不联动父子 */
69
+ setChecked: (data: ZlTreeKey | ZlTreeData, checked: boolean, deep?: boolean) => void;
70
+ /** 全选 / 取消全选(跳过 `props.disabled` 命中的节点;懒加载未展开层级需先 `expandAll()`) */
71
+ setAllChecked: (checked?: boolean) => void;
72
+ /** 清空所有勾选与半选 */
73
+ clearChecked: () => void;
74
+ /** 当前高亮(选中)节点的 key,无选中返回 `null` */
75
+ getCurrentKey: () => ZlTreeKey | null;
76
+ /** 当前高亮节点的数据,无选中返回 `null` */
77
+ getCurrentNode: () => ZlTreeData | null;
78
+ /** 设置高亮节点:传 `null` 取消高亮,`expandParent` 是否自动展开父级 */
79
+ setCurrentKey: (key?: ZlTreeKey | null, expandParent?: boolean) => void;
80
+ /** 按节点实例设置高亮 */
81
+ setCurrentNode: (node: any, expandParent?: boolean) => void;
82
+ /** 按值过滤节点(配合 `filterTreeNode`;传空串恢复全量显示) */
83
+ filter: (value: string) => void;
84
+ /** 展开全部已加载节点 */
85
+ expandAll: () => void;
86
+ /** 收起全部节点 */
87
+ collapseAll: () => void;
88
+ /** 取节点实例(可读 `node.checked` / `node.expanded` / `node.level` 等内部状态) */
89
+ getNode: (data: ZlTreeKey | ZlTreeData) => any;
90
+ /** 取从根到该节点的完整路径数据(面包屑、级联回显用) */
91
+ getNodePath: (data: ZlTreeKey | ZlTreeData) => ZlTreeData[];
92
+ /** 按 key 替换子节点数据(懒加载接口回来后刷新某一支) */
93
+ updateKeyChildren: (key: ZlTreeKey, data: ZlTreeData[]) => void;
94
+ /** 在父节点下追加子节点:`parentData` 传 key / 数据 / 节点实例,缺省追加到根 */
95
+ append: (data: ZlTreeData, parentData?: ZlTreeKey | ZlTreeData | any) => void;
96
+ /** 在参考节点之前插入兄弟节点 */
97
+ insertBefore: (data: ZlTreeData, refData: ZlTreeKey | ZlTreeData | any) => void;
98
+ /** 在参考节点之后插入兄弟节点 */
99
+ insertAfter: (data: ZlTreeData, refData: ZlTreeKey | ZlTreeData | any) => void;
100
+ /** 删除节点(传 key 或节点数据) */
101
+ remove: (data: ZlTreeKey | ZlTreeData | any) => void;
102
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
103
+ "update:checkedKeys": (value: ZlTreeKey[]) => any;
104
+ "update:halfCheckedKeys": (value: ZlTreeKey[]) => any;
105
+ }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
106
+ "onUpdate:checkedKeys"?: ((value: ZlTreeKey[]) => any) | undefined;
107
+ "onUpdate:halfCheckedKeys"?: ((value: ZlTreeKey[]) => any) | undefined;
108
+ }>, {
33
109
  fieldNames: {
34
110
  key?: string;
35
111
  title?: string;
36
112
  children?: string;
113
+ disabled?: string;
114
+ isLeaf?: string;
37
115
  };
116
+ showCheckbox: boolean;
117
+ checkStrictly: boolean;
118
+ checkDescendants: boolean;
38
119
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
39
120
  treeRef: unknown;
40
121
  }, any>;
@@ -1,109 +1,256 @@
1
- import { defineComponent as F, useAttrs as R, useSlots as $, ref as h, computed as r, watch as L, resolveComponent as v, resolveDirective as j, withDirectives as y, openBlock as u, createElementBlock as _, createVNode as n, mergeProps as k, withCtx as a, renderSlot as f, createCommentVNode as N, createElementVNode as g, unref as I, createSlots as K, normalizeProps as S, guardReactiveProps as z, createTextVNode as M, toDisplayString as O, renderList as U, vShow as q, createBlock as G } from "vue";
2
- import H from "../ZlAutoTooltip/index.vue.mjs";
3
- import J from "../ZlEmpty/index.vue.mjs";
4
- import V from "../ZlIcon/index.vue.mjs";
5
- const Q = { class: "zl-tree" }, W = {
1
+ import { defineComponent as J, useModel as x, useAttrs as Q, useSlots as X, ref as w, computed as c, watch as K, nextTick as v, onMounted as Y, resolveComponent as z, resolveDirective as ee, withDirectives as B, openBlock as N, createElementBlock as M, createVNode as i, mergeProps as P, withCtx as p, renderSlot as u, createCommentVNode as T, createElementVNode as V, createSlots as te, normalizeProps as A, guardReactiveProps as b, createTextVNode as le, toDisplayString as oe, renderList as se, vShow as re, createBlock as ne, mergeModels as ce } from "vue";
2
+ import ae from "../ZlAutoTooltip/index.vue.mjs";
3
+ import de from "../ZlEmpty/index.vue.mjs";
4
+ import _ from "../ZlIcon/index.vue.mjs";
5
+ const ie = { class: "zl-tree" }, ue = {
6
6
  key: 0,
7
7
  class: "zl-tree-search"
8
- }, X = { class: "zl-tree-body" }, Y = { class: "zl-tree-node" }, re = /* @__PURE__ */ F({
8
+ }, fe = { class: "zl-tree-body" }, he = { class: "zl-tree-node" }, Ce = /* @__PURE__ */ J({
9
9
  name: "ZlTree",
10
10
  inheritAttrs: !1,
11
11
  __name: "index",
12
- props: {
12
+ props: /* @__PURE__ */ ce({
13
13
  fieldNames: { default: () => ({ key: "key", title: "title", children: "children" }) },
14
14
  inputSearchProps: {},
15
15
  filterTreeNode: {},
16
16
  disableFilter: { type: Boolean },
17
- loading: { type: Boolean }
18
- },
19
- setup(s, { expose: b }) {
20
- const o = s, m = R(), x = $(), i = h(null), c = h(""), P = r(() => ({
21
- label: o.fieldNames.title,
22
- children: o.fieldNames.children
23
- }));
24
- L(c, (e) => {
25
- i.value?.filter(e);
17
+ loading: { type: Boolean },
18
+ showCheckbox: { type: Boolean, default: !1 },
19
+ checkStrictly: { type: Boolean, default: !1 },
20
+ checkDescendants: { type: Boolean, default: !1 }
21
+ }, {
22
+ checkedKeys: {},
23
+ checkedKeysModifiers: {},
24
+ halfCheckedKeys: {},
25
+ halfCheckedKeysModifiers: {}
26
+ }),
27
+ emits: ["update:checkedKeys", "update:halfCheckedKeys"],
28
+ setup(n, { expose: $ }) {
29
+ const f = n, C = x(n, "checkedKeys"), E = x(n, "halfCheckedKeys"), s = Q(), L = X(), l = w(null), h = w(""), D = ["default", "title", "icon"], H = c(() => Object.keys(L).filter((e) => !D.includes(e))), Z = c(() => {
30
+ const e = f.fieldNames, t = {
31
+ label: e.title ?? "title",
32
+ children: e.children ?? "children"
33
+ };
34
+ e.disabled && (t.disabled = e.disabled), e.isLeaf && (t.isLeaf = e.isLeaf);
35
+ const o = s.props ?? {};
36
+ return { ...t, ...o };
37
+ }), F = c(
38
+ () => s["node-key"] ?? s.nodeKey ?? f.fieldNames.key ?? "key"
39
+ ), R = [
40
+ "props",
41
+ "node-key",
42
+ "nodeKey",
43
+ "filter-node-method",
44
+ "filterNodeMethod",
45
+ "onCheck",
46
+ "on-check"
47
+ ], j = c(() => {
48
+ const e = {};
49
+ for (const [t, o] of Object.entries(s))
50
+ R.includes(t) || (e[t] = o);
51
+ return e;
52
+ }), S = c(() => !(s.data ?? []).length);
53
+ K(h, (e) => {
54
+ l.value?.filter(e);
26
55
  });
27
- function w(e, t) {
28
- return e ? String(t[o.fieldNames.title] ?? "").includes(e) : !0;
56
+ function I(e, t) {
57
+ return e ? String(t[f.fieldNames.title ?? "title"] ?? "").includes(e) : !0;
29
58
  }
30
- const B = r(() => o.filterTreeNode ?? w), T = r(() => o.fieldNames.key ?? "key"), p = r(() => !(m.data ?? []).length), C = ["icon", "title"], E = r(() => Object.keys(x).filter((e) => !C.includes(e)));
31
- return b(
32
- new Proxy(
33
- {},
34
- {
35
- get(e, t) {
36
- return i.value?.[t];
37
- },
38
- has(e, t) {
39
- return t in (i.value ?? {});
40
- }
41
- }
42
- )
43
- ), (e, t) => {
44
- const Z = v("el-input"), A = v("el-tree"), D = j("loading");
45
- return y((u(), _("div", Q, [
46
- s.disableFilter ? N("", !0) : (u(), _("div", W, [
47
- n(Z, k({
48
- modelValue: c.value,
49
- "onUpdate:modelValue": t[0] || (t[0] = (l) => c.value = l),
59
+ const O = c(() => {
60
+ const e = s["filter-node-method"] ?? s.filterNodeMethod;
61
+ return typeof e == "function" ? e : f.filterTreeNode ?? I;
62
+ });
63
+ let m = !1;
64
+ function W(e) {
65
+ m = !0, e(), v(() => m = !1);
66
+ }
67
+ function y() {
68
+ const e = C.value;
69
+ !Array.isArray(e) || !l.value || l.value.setCheckedKeys(e);
70
+ }
71
+ function a() {
72
+ W(() => {
73
+ C.value = l.value?.getCheckedKeys?.() ?? [], E.value = l.value?.getHalfCheckedKeys?.() ?? [];
74
+ });
75
+ }
76
+ function U(e, t) {
77
+ a(), q("onCheck", [e, t]);
78
+ }
79
+ function q(e, t) {
80
+ const o = s[e] ?? s[e.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()], g = Array.isArray(o) ? o : [o];
81
+ for (const k of g)
82
+ typeof k == "function" && k(...t);
83
+ }
84
+ K(
85
+ () => C.value,
86
+ () => {
87
+ m || v(y);
88
+ },
89
+ { deep: !0 }
90
+ ), K(
91
+ () => s.data,
92
+ () => {
93
+ v(y);
94
+ }
95
+ ), Y(() => {
96
+ y();
97
+ });
98
+ function G(e = !0) {
99
+ return (l.value?.store?._getAllNodes?.() ?? []).filter((o) => !e || !o.disabled).map((o) => o.key).filter((o) => o != null);
100
+ }
101
+ return $({
102
+ /** 内部 `el-tree` 实例:下面未列出的原生能力(`store` 等)从这里取 */
103
+ get elTree() {
104
+ return l.value;
105
+ },
106
+ /** 勾选节点的 key 数组;`getCheckedKeys(true)` 只取叶子节点 */
107
+ getCheckedKeys: (e) => l.value?.getCheckedKeys(e) ?? [],
108
+ /** 勾选节点的数据数组;`leafOnly` 只要叶子,`includeHalfChecked` 连半选节点一起返回 */
109
+ getCheckedNodes: (e, t) => l.value?.getCheckedNodes(e, t) ?? [],
110
+ /** 半选节点的 key 数组(父子联动下部分勾选的父节点) */
111
+ getHalfCheckedKeys: () => l.value?.getHalfCheckedKeys() ?? [],
112
+ /** 半选节点的数据数组 */
113
+ getHalfCheckedNodes: () => l.value?.getHalfCheckedNodes() ?? [],
114
+ /** 按 key 数组设置勾选;`leafOnly` 表示这些 key 只对应叶子节点(父节点由联动推导) */
115
+ setCheckedKeys: (e, t) => {
116
+ l.value?.setCheckedKeys(e, t), a();
117
+ },
118
+ /** 设置单个节点勾选态:`data` 传 key 或节点数据,`deep=false` 表示不联动父子 */
119
+ setChecked: (e, t, o = !0) => {
120
+ l.value?.setChecked(e, t, o), a();
121
+ },
122
+ /** 全选 / 取消全选(跳过 `props.disabled` 命中的节点;懒加载未展开层级需先 `expandAll()`) */
123
+ setAllChecked: (e = !0) => {
124
+ const t = e ? G() : [];
125
+ l.value?.setCheckedKeys(t), a();
126
+ },
127
+ /** 清空所有勾选与半选 */
128
+ clearChecked: () => {
129
+ l.value?.setCheckedKeys([]), a();
130
+ },
131
+ /** 当前高亮(选中)节点的 key,无选中返回 `null` */
132
+ getCurrentKey: () => l.value?.getCurrentKey() ?? null,
133
+ /** 当前高亮节点的数据,无选中返回 `null` */
134
+ getCurrentNode: () => l.value?.getCurrentNode() ?? null,
135
+ /** 设置高亮节点:传 `null` 取消高亮,`expandParent` 是否自动展开父级 */
136
+ setCurrentKey: (e, t = !0) => {
137
+ l.value?.setCurrentKey(e, t);
138
+ },
139
+ /** 按节点实例设置高亮 */
140
+ setCurrentNode: (e, t = !0) => {
141
+ l.value?.setCurrentNode(e, t);
142
+ },
143
+ /** 按值过滤节点(配合 `filterTreeNode`;传空串恢复全量显示) */
144
+ filter: (e) => {
145
+ h.value = e, l.value?.filter(e);
146
+ },
147
+ /** 展开全部已加载节点 */
148
+ expandAll: () => {
149
+ (l.value?.store?._getAllNodes?.() ?? []).forEach((t) => t.expand());
150
+ },
151
+ /** 收起全部节点 */
152
+ collapseAll: () => {
153
+ (l.value?.store?._getAllNodes?.() ?? []).forEach((t) => t.collapse());
154
+ },
155
+ /** 取节点实例(可读 `node.checked` / `node.expanded` / `node.level` 等内部状态) */
156
+ getNode: (e) => l.value?.getNode(e),
157
+ /** 取从根到该节点的完整路径数据(面包屑、级联回显用) */
158
+ getNodePath: (e) => l.value?.getNodePath(e) ?? [],
159
+ /** 按 key 替换子节点数据(懒加载接口回来后刷新某一支) */
160
+ updateKeyChildren: (e, t) => {
161
+ l.value?.updateKeyChildren(e, t), v(y);
162
+ },
163
+ /** 在父节点下追加子节点:`parentData` 传 key / 数据 / 节点实例,缺省追加到根 */
164
+ append: (e, t) => {
165
+ l.value?.append(e, t);
166
+ },
167
+ /** 在参考节点之前插入兄弟节点 */
168
+ insertBefore: (e, t) => {
169
+ l.value?.insertBefore(e, t);
170
+ },
171
+ /** 在参考节点之后插入兄弟节点 */
172
+ insertAfter: (e, t) => {
173
+ l.value?.insertAfter(e, t);
174
+ },
175
+ /** 删除节点(传 key 或节点数据) */
176
+ remove: (e) => {
177
+ l.value?.remove(e);
178
+ }
179
+ }), (e, t) => {
180
+ const o = z("el-input"), g = z("el-tree"), k = ee("loading");
181
+ return B((N(), M("div", ie, [
182
+ n.disableFilter ? T("", !0) : (N(), M("div", ue, [
183
+ i(o, P({
184
+ modelValue: h.value,
185
+ "onUpdate:modelValue": t[0] || (t[0] = (r) => h.value = r),
50
186
  clearable: ""
51
- }, s.inputSearchProps, { "suffix-icon": null }), {
52
- suffix: a(() => [
53
- n(V, {
187
+ }, n.inputSearchProps, { "suffix-icon": null }), {
188
+ suffix: p(() => [
189
+ i(_, {
54
190
  icon: "zl:search",
55
191
  style: { cursor: "pointer" }
56
192
  })
57
193
  ]),
58
194
  _: 1
59
195
  }, 16, ["modelValue"]),
60
- f(e.$slots, "search-extra")
196
+ u(e.$slots, "search-extra")
61
197
  ])),
62
- g("div", X, [
63
- y(n(A, k({
198
+ V("div", fe, [
199
+ B(i(g, P({
64
200
  ref_key: "treeRef",
65
- ref: i
66
- }, I(m), {
67
- props: P.value,
68
- "node-key": T.value,
69
- "filter-node-method": B.value
70
- }), K({
71
- default: a(({ node: l, data: d }) => [
72
- f(e.$slots, "title", S(z({ node: l, data: d })), () => [
73
- g("span", Y, [
74
- n(V, {
75
- icon: l.isLeaf ? "zl:document-color" : "zl:folder-color",
76
- class: "zl-tree-node__icon"
77
- }, null, 8, ["icon"]),
78
- n(H, null, {
79
- default: a(() => [
80
- M(O(l.label), 1)
201
+ ref: l
202
+ }, j.value, {
203
+ props: Z.value,
204
+ "node-key": F.value,
205
+ "filter-node-method": O.value,
206
+ "show-checkbox": n.showCheckbox,
207
+ "check-strictly": n.checkStrictly,
208
+ "check-descendants": n.checkDescendants,
209
+ onCheck: U
210
+ }), te({
211
+ default: p(({ node: r, data: d }) => [
212
+ u(e.$slots, "default", {
213
+ node: r,
214
+ data: d
215
+ }, () => [
216
+ u(e.$slots, "title", A(b({ node: r, data: d })), () => [
217
+ V("span", he, [
218
+ u(e.$slots, "icon", A(b({ node: r, data: d })), () => [
219
+ i(_, {
220
+ icon: r.isLeaf ? "zl:document-color" : "zl:folder-color",
221
+ class: "zl-tree-node__icon"
222
+ }, null, 8, ["icon"])
81
223
  ]),
82
- _: 2
83
- }, 1024)
224
+ i(ae, null, {
225
+ default: p(() => [
226
+ le(oe(r.label), 1)
227
+ ]),
228
+ _: 2
229
+ }, 1024)
230
+ ])
84
231
  ])
85
232
  ])
86
233
  ]),
87
234
  _: 2
88
235
  }, [
89
- U(E.value, (l) => ({
90
- name: l,
91
- fn: a((d) => [
92
- f(e.$slots, l, S(z(d)))
236
+ se(H.value, (r) => ({
237
+ name: r,
238
+ fn: p((d) => [
239
+ u(e.$slots, r, A(b(d)))
93
240
  ])
94
241
  }))
95
- ]), 1040, ["props", "node-key", "filter-node-method"]), [
96
- [q, !p.value]
242
+ ]), 1040, ["props", "node-key", "filter-node-method", "show-checkbox", "check-strictly", "check-descendants"]), [
243
+ [re, !S.value]
97
244
  ]),
98
- p.value ? (u(), G(J, { key: 0 })) : N("", !0)
245
+ S.value ? (N(), ne(de, { key: 0 })) : T("", !0)
99
246
  ])
100
247
  ])), [
101
- [D, s.loading]
248
+ [k, n.loading]
102
249
  ]);
103
250
  };
104
251
  }
105
252
  });
106
253
  export {
107
- re as default
254
+ Ce as default
108
255
  };
109
256
  //# sourceMappingURL=index.vue.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zl-ui-kit/components",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "ZL UI 业务组件库(Element Plus 体系,Zl 前缀)——首批:Icon/AutoTooltip/Tag/CornerTag/Text/Title/Copy/Empty/Pagination/DictTag",
6
6
  "license": "MIT",
@@ -39,9 +39,9 @@
39
39
  "file-type": "^20.4.1",
40
40
  "dt-sql-parser": "^4.3.1",
41
41
  "sql-formatter": "^15.4.2",
42
- "@zl-ui-kit/composables": "0.8.3",
43
- "@zl-ui-kit/utils": "0.8.3",
44
- "@zl-ui-kit/icons": "0.8.3"
42
+ "@zl-ui-kit/utils": "0.9.0",
43
+ "@zl-ui-kit/composables": "0.9.0",
44
+ "@zl-ui-kit/icons": "0.9.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@vueuse/core": "^12.3.0",
@@ -98,10 +98,10 @@
98
98
  "@vue-office/pdf": "^2.0.10",
99
99
  "@vue-office/pptx": "1.0.1",
100
100
  "echarts": "^5.6.0",
101
- "@jichuang/vite-config": "1.0.0",
102
101
  "@jichuang/eslint-config": "1.0.0",
102
+ "@zl-ui-kit/theme": "0.9.0",
103
103
  "@jichuang/tsconfig": "1.0.0",
104
- "@zl-ui-kit/theme": "0.8.3"
104
+ "@jichuang/vite-config": "1.0.0"
105
105
  },
106
106
  "repository": {
107
107
  "type": "git",