bkui-vue 3.0.4 → 3.0.5

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/lib/tree/index.js CHANGED
@@ -17334,8 +17334,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
17334
17334
 
17335
17335
  ;// external "../shared"
17336
17336
 
17337
- ;// external "vue"
17338
-
17339
17337
  ;// ../../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
17340
17338
  function _arrayWithHoles(r) {
17341
17339
  if (Array.isArray(r)) return r;
@@ -17401,6 +17399,8 @@ function _slicedToArray(r, e) {
17401
17399
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
17402
17400
  }
17403
17401
 
17402
+ ;// external "vue"
17403
+
17404
17404
  ;// external "../config-provider"
17405
17405
 
17406
17406
  ;// external "../virtual-render"
@@ -17524,6 +17524,8 @@ var NODE_ATTRIBUTES;
17524
17524
  NODE_ATTRIBUTES["ORDER"] = "__order";
17525
17525
  NODE_ATTRIBUTES["PARENT"] = "__parent";
17526
17526
  NODE_ATTRIBUTES["PATH"] = "__path";
17527
+ /** 同级是否存在下一个兄弟(用于 level-line,避免渲染时 indexOf) */
17528
+ NODE_ATTRIBUTES["HAS_NEXT_SIBLING"] = "__has_next_sibling";
17527
17529
  NODE_ATTRIBUTES["TREE_NODE_ATTR"] = "__attr__";
17528
17530
  NODE_ATTRIBUTES["UUID"] = "__uuid";
17529
17531
  })(NODE_ATTRIBUTES || (NODE_ATTRIBUTES = {}));
@@ -17787,6 +17789,69 @@ var treeProps = {
17787
17789
  callback: __WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_shared_edbdfb03_PropTypes__.func.def(undefined)
17788
17790
  })]).def(false)
17789
17791
  };
17792
+ ;// ../../packages/tree/src/tree-node-row.tsx
17793
+ /*
17794
+ * Tencent is pleased to support the open source community by making
17795
+ * 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community Edition) available.
17796
+ *
17797
+ * Copyright (C) 2025 Tencent. All rights reserved.
17798
+ *
17799
+ * 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community Edition) is licensed under the MIT License.
17800
+ *
17801
+ * License for 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community Edition):
17802
+ *
17803
+ * ---------------------------------------------------
17804
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
17805
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
17806
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
17807
+ * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
17808
+ *
17809
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
17810
+ * the Software.
17811
+ *
17812
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
17813
+ * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17814
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17815
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
17816
+ * IN THE SOFTWARE.
17817
+ */
17818
+
17819
+ /**
17820
+ * 独立树行组件:仅在 version / globalVersion 变化时重渲染。
17821
+ * 展开/选中时避免所有可见行的自定义插槽被连带重跑。
17822
+ */
17823
+ /* harmony default export */ const tree_node_row = (__WEBPACK_EXTERNAL_MODULE_vue_defineComponent__({
17824
+ name: 'BkTreeNodeRow',
17825
+ props: {
17826
+ item: {
17827
+ type: Object,
17828
+ required: true
17829
+ },
17830
+ showTree: {
17831
+ type: Boolean,
17832
+ "default": true
17833
+ },
17834
+ version: {
17835
+ type: Number,
17836
+ "default": 0
17837
+ },
17838
+ globalVersion: {
17839
+ type: Number,
17840
+ "default": 0
17841
+ },
17842
+ renderFn: {
17843
+ type: Function,
17844
+ required: true
17845
+ }
17846
+ },
17847
+ setup: function setup(props) {
17848
+ return function () {
17849
+ void props.version;
17850
+ void props.globalVersion;
17851
+ return props.renderFn(props.item, props.showTree);
17852
+ };
17853
+ }
17854
+ }));
17790
17855
  ;// external "../exception"
17791
17856
 
17792
17857
  ;// external "../exception/exception.less"
@@ -18281,19 +18346,25 @@ var treeProps = {
18281
18346
  }
18282
18347
  };
18283
18348
  var getNodeById = function getNodeById(id) {
18284
- var _flatData$nodeMap$get, _flatData$nodeMap;
18285
- return (_flatData$nodeMap$get = (_flatData$nodeMap = flatData.nodeMap) === null || _flatData$nodeMap === void 0 ? void 0 : _flatData$nodeMap.get("".concat(id))) !== null && _flatData$nodeMap$get !== void 0 ? _flatData$nodeMap$get : flatData.data.find(function (item) {
18286
- return "".concat(getNodeId(item)) === "".concat(id);
18287
- });
18349
+ var _flatData$nodeMap;
18350
+ if (id === undefined || id === null || id === '') {
18351
+ return undefined;
18352
+ }
18353
+ // 禁止回退 flatData.data.find(百万节点 O(N))
18354
+ return (_flatData$nodeMap = flatData.nodeMap) === null || _flatData$nodeMap === void 0 ? void 0 : _flatData$nodeMap.get("".concat(id));
18288
18355
  };
18289
- var setNodeAttrById = function setNodeAttrById(id, attr, val) {
18356
+ var setNodeAttrById = function setNodeAttrById(id, attr, val, setOptions) {
18290
18357
  if (Array.isArray(id)) {
18291
18358
  Array.prototype.forEach.call(id, function (item) {
18292
- return setNodeAttr(getNodeById(item), attr, val, id);
18359
+ return setNodeAttr(getNodeById(item), attr, val, id, setOptions);
18293
18360
  });
18294
18361
  return;
18295
18362
  }
18296
- setNodeAttr(getNodeById(id), attr, val, id);
18363
+ var node = getNodeById(id);
18364
+ if (!node) {
18365
+ return;
18366
+ }
18367
+ setNodeAttr(node, attr, val, id, setOptions);
18297
18368
  };
18298
18369
  var getNodePath = function getNodePath(node) {
18299
18370
  return getNodeAttr(node, NODE_ATTRIBUTES.PATH);
@@ -18408,17 +18479,24 @@ var treeProps = {
18408
18479
  var getParentNodeAttr = function getParentNodeAttr(node, attrName) {
18409
18480
  return getNodeAttr(getNodeAttr(node, NODE_ATTRIBUTES.PARENT), attrName);
18410
18481
  };
18411
- var isParentNodeOpened = function isParentNodeOpened(node) {
18412
- return isItemOpen(getNodeAttr(node, NODE_ATTRIBUTES.PARENT));
18413
- };
18414
18482
  /**
18415
- * 过滤当前状态为Open的节点
18416
- * 页面展示只会展示Open的节点
18417
- * @param item
18418
- * @returns
18483
+ * 判定节点是否应出现在可见列表中:
18484
+ * 根节点始终可见;非根节点仅当所有祖先均为展开时可见。
18485
+ * 注意:不能用「自身 isOpen」——否则父节点收起后,仍 open 的子节点会残留在列表中,
18486
+ * 出现「图标收起、内容仍展开」的不一致(搜索清空后尤其明显)。
18419
18487
  */
18420
18488
  var checkNodeIsOpen = function checkNodeIsOpen(node) {
18421
- return isRootNode(node) || isItemOpen(node) || isParentNodeOpened(node);
18489
+ if (isRootNode(node)) {
18490
+ return true;
18491
+ }
18492
+ var parent = getParentNode(node);
18493
+ while (parent) {
18494
+ if (!isNodeOpened(parent)) {
18495
+ return false;
18496
+ }
18497
+ parent = getParentNode(parent);
18498
+ }
18499
+ return true;
18422
18500
  };
18423
18501
  /**
18424
18502
  * 根据节点path返回源数据中节点信息
@@ -18469,13 +18547,17 @@ var treeProps = {
18469
18547
  return _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING], getNodeAttr(item, NODE_ATTRIBUTES.IS_LOADING)), NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.HAS_CHILD], hasChildNode(item)), NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_MATCH], isNodeMatched(item)), NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_CHECKED], isNodeChecked(item)), NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_OPEN], isNodeOpened(item)), NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_ROOT], isRootNode(item)), "fullPath", getNodeAttr(item, NODE_ATTRIBUTES.PATH)), "uuid", getNodeId(item)), "parent", getNodeAttr(item, NODE_ATTRIBUTES.PARENT)), "parentId", getNodeId(getNodeAttr(item, NODE_ATTRIBUTES.PARENT)));
18470
18548
  };
18471
18549
  var extendNodeAttr = function extendNodeAttr(item) {
18472
- return Object.assign({}, item, _defineProperty({}, NODE_ATTRIBUTES.TREE_NODE_ATTR, resolveScopedSlotParam(item)));
18550
+ return __WEBPACK_EXTERNAL_MODULE_vue_markRaw__(Object.assign({}, __WEBPACK_EXTERNAL_MODULE_vue_toRaw__(item), _defineProperty({}, NODE_ATTRIBUTES.TREE_NODE_ATTR, resolveScopedSlotParam(item))));
18473
18551
  };
18552
+ /**
18553
+ * 插槽参数:data 使用 toRaw,避免深层 Proxy;整体 markRaw,降低自定义渲染时的响应式开销。
18554
+ * 注意:data 仍持有原 children 引用,业务侧勿对整棵 data 做 JSON.stringify。
18555
+ */
18474
18556
  var extendNodeScopedData = function extendNodeScopedData(item) {
18475
- return {
18476
- data: item,
18557
+ return __WEBPACK_EXTERNAL_MODULE_vue_markRaw__({
18558
+ data: __WEBPACK_EXTERNAL_MODULE_vue_toRaw__(item),
18477
18559
  attributes: resolveScopedSlotParam(item)
18478
- };
18560
+ });
18479
18561
  };
18480
18562
  /**
18481
18563
  * 组装进入可视区域元素返回数据
@@ -19201,6 +19283,7 @@ var use_node_action_this = undefined;
19201
19283
  /* harmony default export */ const use_node_action = (function (props, ctx, flatData, _renderData, initOption) {
19202
19284
  // const checkedNodes = [];
19203
19285
  var selectedNodeId = props.selected;
19286
+ var selectedNode = null;
19204
19287
  var _useNodeAttribute = use_node_attribute(flatData, props),
19205
19288
  setNodeAttr = _useNodeAttribute.setNodeAttr,
19206
19289
  setNodeAttrById = _useNodeAttribute.setNodeAttrById,
@@ -19217,8 +19300,7 @@ var use_node_action_this = undefined;
19217
19300
  getParentNode = _useNodeAttribute.getParentNode,
19218
19301
  resolveScopedSlotParam = _useNodeAttribute.resolveScopedSlotParam,
19219
19302
  extendNodeAttr = _useNodeAttribute.extendNodeAttr,
19220
- extendNodeScopedData = _useNodeAttribute.extendNodeScopedData,
19221
- getRootNodeList = _useNodeAttribute.getRootNodeList;
19303
+ extendNodeScopedData = _useNodeAttribute.extendNodeScopedData;
19222
19304
  var _usePrefix = __WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_config_provider_fe8577a3_usePrefix__(),
19223
19305
  resolveClassName = _usePrefix.resolveClassName;
19224
19306
  var registerNextLoop = initOption.registerNextLoop,
@@ -19285,18 +19367,18 @@ var use_node_action_this = undefined;
19285
19367
  /**
19286
19368
  * 根据节点状态获取节点操作Icon
19287
19369
  * @param item
19288
- * @returns
19370
+ * @param scopedData 可选,同一行渲染内复用,避免重复 Object.assign / resolveScopedSlotParam
19289
19371
  */
19290
- var getActionIcon = function getActionIcon(item) {
19372
+ var getActionIcon = function getActionIcon(item, scopedData) {
19291
19373
  if (ctx.slots.nodeAction) {
19292
- return ctx.slots.nodeAction(getScopedSlotData(item));
19374
+ return ctx.slots.nodeAction(scopedData !== null && scopedData !== void 0 ? scopedData : getScopedSlotData(item));
19293
19375
  }
19294
19376
  var prefixFnVal = null;
19295
19377
  if (isNodeLoading(item)) {
19296
19378
  return getLoadingIcon(item);
19297
19379
  }
19298
19380
  if (typeof props.prefixIcon === 'function') {
19299
- prefixFnVal = props.prefixIcon(getScopedSlotData(item), 'node_action');
19381
+ prefixFnVal = props.prefixIcon(scopedData !== null && scopedData !== void 0 ? scopedData : getScopedSlotData(item), 'node_action');
19300
19382
  if (prefixFnVal !== 'default') {
19301
19383
  return renderPrefixVal(prefixFnVal);
19302
19384
  }
@@ -19316,18 +19398,18 @@ var use_node_action_this = undefined;
19316
19398
  /**
19317
19399
  * 获取节点类型Icon
19318
19400
  * @param item
19319
- * @returns
19401
+ * @param scopedData 可选,同一行渲染内复用
19320
19402
  */
19321
- var getNodePrefixIcon = function getNodePrefixIcon(item) {
19403
+ var getNodePrefixIcon = function getNodePrefixIcon(item, scopedData) {
19322
19404
  if (!props.showNodeTypeIcon) {
19323
19405
  return null;
19324
19406
  }
19325
19407
  if (ctx.slots.nodeType) {
19326
- return ctx.slots.nodeType(getScopedSlotData(item));
19408
+ return ctx.slots.nodeType(scopedData !== null && scopedData !== void 0 ? scopedData : getScopedSlotData(item));
19327
19409
  }
19328
19410
  var prefixFnVal = null;
19329
19411
  if (typeof props.prefixIcon === 'function') {
19330
- prefixFnVal = props.prefixIcon(getScopedSlotData(item), 'node_type');
19412
+ prefixFnVal = props.prefixIcon(scopedData !== null && scopedData !== void 0 ? scopedData : getScopedSlotData(item), 'node_type');
19331
19413
  if (prefixFnVal !== 'default') {
19332
19414
  return renderPrefixVal(prefixFnVal);
19333
19415
  }
@@ -19382,7 +19464,12 @@ var use_node_action_this = undefined;
19382
19464
  updateParentChecked(item);
19383
19465
  }
19384
19466
  if (options.refresh !== false) {
19385
- scheduleUiRefresh === null || scheduleUiRefresh === void 0 || scheduleUiRefresh();
19467
+ // 级联勾选可能影响大量节点,走全局刷新;单节点勾选只刷新当前行
19468
+ if (isCascadeEnabled(props)) {
19469
+ scheduleUiRefresh === null || scheduleUiRefresh === void 0 || scheduleUiRefresh();
19470
+ } else {
19471
+ scheduleUiRefresh === null || scheduleUiRefresh === void 0 || scheduleUiRefresh(item);
19472
+ }
19386
19473
  }
19387
19474
  if (options.emitEvent !== false) {
19388
19475
  emitCheckedChange();
@@ -19398,8 +19485,13 @@ var use_node_action_this = undefined;
19398
19485
  var isIndeterminate = function isIndeterminate(item) {
19399
19486
  return isNodeIndeterminate(item);
19400
19487
  };
19401
- var getCheckboxRender = function getCheckboxRender(item) {
19402
- if (!showCheckbox(props, extendNodeScopedData(item))) {
19488
+ var getCheckboxRender = function getCheckboxRender(item, scopedData) {
19489
+ // showCheckbox 函数形态需要 { data, attributes };布尔形态直接短路
19490
+ if (typeof props.showCheckbox === 'function') {
19491
+ if (!showCheckbox(props, scopedData !== null && scopedData !== void 0 && scopedData.data ? scopedData : extendNodeScopedData(item))) {
19492
+ return null;
19493
+ }
19494
+ } else if (!showCheckbox(props, item)) {
19403
19495
  return null;
19404
19496
  }
19405
19497
  return __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("span", {
@@ -19571,6 +19663,21 @@ var use_node_action_this = undefined;
19571
19663
  * @param triggerEvent 是否触发抛出事件 false
19572
19664
  * @returns
19573
19665
  */
19666
+ var _resolveSelectedPropId = function resolveSelectedPropId(value) {
19667
+ if (value === undefined || value === null || value === '') {
19668
+ return undefined;
19669
+ }
19670
+ if (Array.isArray(value)) {
19671
+ return _resolveSelectedPropId(value[0]);
19672
+ }
19673
+ if (typeof value === 'string' || typeof value === 'number' || _typeof(value) === 'symbol') {
19674
+ return value;
19675
+ }
19676
+ if (_typeof(value) === 'object') {
19677
+ return getNodeId(value);
19678
+ }
19679
+ return value;
19680
+ };
19574
19681
  var _setSelect = function setSelect(nodes) {
19575
19682
  var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19576
19683
  var autoOpen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
@@ -19582,11 +19689,10 @@ var use_node_action_this = undefined;
19582
19689
  }
19583
19690
  var resolvedItem = resolveNodeItem(nodeList[0]);
19584
19691
  if (typeof resolvedItem === 'number' || typeof resolvedItem === 'string' || _typeof(resolvedItem) === 'symbol') {
19585
- var _ref, _flatData$nodeMap$get, _flatData$nodeMap;
19692
+ var _flatData$nodeMap$get, _flatData$nodeMap;
19586
19693
  var nodeId = String(resolvedItem);
19587
- resolvedItem = (_ref = (_flatData$nodeMap$get = (_flatData$nodeMap = flatData.nodeMap) === null || _flatData$nodeMap === void 0 ? void 0 : _flatData$nodeMap.get(nodeId)) !== null && _flatData$nodeMap$get !== void 0 ? _flatData$nodeMap$get : flatData.data.find(function (item) {
19588
- return "".concat(getNodeId(item)) === nodeId;
19589
- })) !== null && _ref !== void 0 ? _ref : _defineProperty({}, NODE_ATTRIBUTES.IS_NULL, true);
19694
+ // 只走 nodeMap,禁止 data.find O(N)
19695
+ resolvedItem = (_flatData$nodeMap$get = (_flatData$nodeMap = flatData.nodeMap) === null || _flatData$nodeMap === void 0 ? void 0 : _flatData$nodeMap.get(nodeId)) !== null && _flatData$nodeMap$get !== void 0 ? _flatData$nodeMap$get : _defineProperty({}, NODE_ATTRIBUTES.IS_NULL, true);
19590
19696
  }
19591
19697
  if (resolvedItem[NODE_ATTRIBUTES.IS_NULL]) {
19592
19698
  return;
@@ -19595,14 +19701,39 @@ var use_node_action_this = undefined;
19595
19701
  console.warn('props.selectable is false or undefined, please set selectable with true');
19596
19702
  return;
19597
19703
  }
19598
- if (selectedNodeId !== null && selectedNodeId !== undefined) {
19599
- setNodeAttrById(selectedNodeId, NODE_ATTRIBUTES.IS_SELECTED, !selected);
19704
+ var nextId = getNodeId(resolvedItem);
19705
+ var nextIdKey = nextId === undefined || nextId === null ? '' : String(nextId);
19706
+ var selectedIdKey = selectedNodeId === undefined || selectedNodeId === null ? '' : String(selectedNodeId);
19707
+ var alreadySelected = selected && selectedIdKey !== '' && selectedIdKey === nextIdKey && !!getNodeAttr(resolvedItem, NODE_ATTRIBUTES.IS_SELECTED);
19708
+ // 已选中同一节点:完全短路(含受控 selected 数组每次新引用触发的同步)
19709
+ // 展开由 content click / 箭头自行处理,避免重复 setOpen → expandVisibleNode
19710
+ if (alreadySelected) {
19711
+ return;
19600
19712
  }
19601
- if (props.selected && props.selected !== selectedNodeId) {
19602
- setNodeAttrById(props.selected, NODE_ATTRIBUTES.IS_SELECTED, !selected);
19713
+ // 取消旧选中:优先用缓存节点引用,避免 setNodeAttrById → 全表查找
19714
+ if (selectedNode && selectedNode !== resolvedItem) {
19715
+ setNodeAttr(selectedNode, NODE_ATTRIBUTES.IS_SELECTED, false, undefined, {
19716
+ silent: true
19717
+ });
19718
+ scheduleUiRefresh === null || scheduleUiRefresh === void 0 || scheduleUiRefresh(selectedNode);
19719
+ } else if (selectedIdKey && selectedIdKey !== nextIdKey) {
19720
+ setNodeAttrById(selectedNodeId, NODE_ATTRIBUTES.IS_SELECTED, false, {
19721
+ silent: true
19722
+ });
19603
19723
  }
19604
- setNodeAttr(resolvedItem, NODE_ATTRIBUTES.IS_SELECTED, selected);
19605
- selectedNodeId = getNodeId(resolvedItem);
19724
+ var selectedPropId = _resolveSelectedPropId(props.selected);
19725
+ var selectedPropKey = selectedPropId === undefined || selectedPropId === null ? '' : String(selectedPropId);
19726
+ if (selectedPropKey && selectedPropKey !== nextIdKey && selectedPropKey !== selectedIdKey) {
19727
+ setNodeAttrById(selectedPropId, NODE_ATTRIBUTES.IS_SELECTED, false, {
19728
+ silent: true
19729
+ });
19730
+ }
19731
+ setNodeAttr(resolvedItem, NODE_ATTRIBUTES.IS_SELECTED, selected, undefined, {
19732
+ silent: true
19733
+ });
19734
+ selectedNode = resolvedItem;
19735
+ selectedNodeId = nextId;
19736
+ scheduleUiRefresh === null || scheduleUiRefresh === void 0 || scheduleUiRefresh(resolvedItem);
19606
19737
  if (triggerEvent) {
19607
19738
  ctx.emit(EVENTS.NODE_SELECTED, {
19608
19739
  selected: selected,
@@ -19703,7 +19834,7 @@ var use_node_action_this = undefined;
19703
19834
  if (depth > nodeDepth) {
19704
19835
  return false;
19705
19836
  }
19706
- // 取 depth 层祖先,判断其是否存在下一个兄弟节点 —— O(depth) 替代全表 some
19837
+ // 取 depth 层祖先,用 flatten 预计算的 HAS_NEXT_SIBLING,避免 siblings.indexOf O(兄弟数)
19707
19838
  var ancestor = node;
19708
19839
  for (var i = nodeDepth; i > depth; i--) {
19709
19840
  ancestor = getParentNode(ancestor);
@@ -19711,10 +19842,7 @@ var use_node_action_this = undefined;
19711
19842
  return false;
19712
19843
  }
19713
19844
  }
19714
- var parent = getParentNode(ancestor);
19715
- var siblings = parent ? getChildNodes(parent) : getRootNodeList();
19716
- var idx = siblings.indexOf(ancestor);
19717
- return idx >= 0 && idx < siblings.length - 1;
19845
+ return !!getNodeAttr(ancestor, NODE_ATTRIBUTES.HAS_NEXT_SIBLING);
19718
19846
  };
19719
19847
  /**
19720
19848
  * 获取层级连线
@@ -19730,35 +19858,31 @@ var use_node_action_this = undefined;
19730
19858
  if (isRootNode(node)) {
19731
19859
  return null;
19732
19860
  }
19733
- var getNodeLineStyle = function getNodeLineStyle(dpth) {
19734
- return {
19735
- '--depth': dpth
19736
- };
19737
- };
19738
19861
  var maxDeep = ((_getNodeAttr2 = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr2 !== void 0 ? _getNodeAttr2 : 0) + 1;
19739
- return new Array(maxDeep).fill('').map(function (_, index) {
19740
- return index;
19741
- }).filter(function (depth) {
19742
- return filterNextNode(depth, node);
19743
- }).filter(function (depth) {
19744
- return depth > 0;
19745
- })
19746
- // @ts-ignore:next-line
19747
- .map(function (index) {
19748
- return __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("span", {
19749
- "style": getNodeLineStyle(maxDeep - index),
19862
+ var lines = [];
19863
+ for (var depth = 1; depth < maxDeep; depth++) {
19864
+ if (!filterNextNode(depth, node)) {
19865
+ continue;
19866
+ }
19867
+ lines.push(__WEBPACK_EXTERNAL_MODULE_vue_createVNode__("span", {
19868
+ "style": {
19869
+ '--depth': maxDeep - depth
19870
+ },
19750
19871
  "class": "node-virtual-line"
19751
- }, null);
19752
- });
19872
+ }, null));
19873
+ }
19874
+ return lines.length ? lines : null;
19753
19875
  };
19754
- var renderNodeSlots = function renderNodeSlots(item) {
19876
+ var renderNodeSlots = function renderNodeSlots(item, options) {
19877
+ // #node:参数为 { ...node, ...attributes }(keepSlotData=false 时)
19755
19878
  if (ctx.slots.node) {
19756
- var _ctx$slots$node, _ctx$slots2;
19757
- return (_ctx$slots$node = (_ctx$slots2 = ctx.slots).node) === null || _ctx$slots$node === void 0 ? void 0 : _ctx$slots$node.call(_ctx$slots2, getScopedSlotData(item));
19879
+ var _ctx$slots$node, _ctx$slots2, _options$nodeScoped;
19880
+ return (_ctx$slots$node = (_ctx$slots2 = ctx.slots).node) === null || _ctx$slots$node === void 0 ? void 0 : _ctx$slots$node.call(_ctx$slots2, (_options$nodeScoped = options === null || options === void 0 ? void 0 : options.nodeScoped) !== null && _options$nodeScoped !== void 0 ? _options$nodeScoped : getScopedSlotData(item));
19758
19881
  }
19882
+ // #default:参数为 { data, attributes }
19759
19883
  if (ctx.slots["default"]) {
19760
- var _ctx$slots$default, _ctx$slots3;
19761
- return (_ctx$slots$default = (_ctx$slots3 = ctx.slots)["default"]) === null || _ctx$slots$default === void 0 ? void 0 : _ctx$slots$default.call(_ctx$slots3, extendNodeScopedData(item));
19884
+ var _ctx$slots$default, _ctx$slots3, _options$defaultScope;
19885
+ return (_ctx$slots$default = (_ctx$slots3 = ctx.slots)["default"]) === null || _ctx$slots$default === void 0 ? void 0 : _ctx$slots$default.call(_ctx$slots3, (_options$defaultScope = options === null || options === void 0 ? void 0 : options.defaultScoped) !== null && _options$defaultScope !== void 0 ? _options$defaultScope : extendNodeScopedData(item));
19762
19886
  }
19763
19887
  return [getLabel(item, props)];
19764
19888
  };
@@ -19780,7 +19904,28 @@ var use_node_action_this = undefined;
19780
19904
  var renderTreeNode = function renderTreeNode(item) {
19781
19905
  var _ctx$slots$nodeAppend, _ctx$slots4;
19782
19906
  var showTree = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19783
- var child = getActionIcon(item);
19907
+ // 同一行内按需各生成一次,避免 prefixIcon / 多插槽重复构造 scoped 参数
19908
+ var attrScoped = null;
19909
+ var defaultScoped = null;
19910
+ var getAttrScoped = function getAttrScoped() {
19911
+ if (!attrScoped) {
19912
+ attrScoped = getScopedSlotData(item);
19913
+ }
19914
+ return attrScoped;
19915
+ };
19916
+ var getDefaultScoped = function getDefaultScoped() {
19917
+ // keepSlotData 时两种插槽格式一致,可复用
19918
+ if (props.keepSlotData) {
19919
+ return getAttrScoped();
19920
+ }
19921
+ if (!defaultScoped) {
19922
+ defaultScoped = extendNodeScopedData(item);
19923
+ }
19924
+ return defaultScoped;
19925
+ };
19926
+ var needAttrScoped = ctx.slots.nodeAction || ctx.slots.nodeType || ctx.slots.nodeAppend || ctx.slots.node || typeof props.prefixIcon === 'function';
19927
+ var rowAttrScoped = needAttrScoped ? getAttrScoped() : null;
19928
+ var child = getActionIcon(item, rowAttrScoped);
19784
19929
  return __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("div", {
19785
19930
  "key": getNodeId(item),
19786
19931
  "class": [getNodeRowClass(item, flatData.schema), _defineProperty({}, resolveClassName('tree-node-draggable'), props.draggable || props.dragSort)],
@@ -19799,9 +19944,12 @@ var use_node_action_this = undefined;
19799
19944
  }
19800
19945
  }, [child]), __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("div", {
19801
19946
  "class": resolveClassName('node-content')
19802
- }, [[getCheckboxRender(item), getNodePrefixIcon(item)], __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("span", {
19947
+ }, [[getCheckboxRender(item, typeof props.showCheckbox === 'function' ? getDefaultScoped() : null), getNodePrefixIcon(item, rowAttrScoped)], __WEBPACK_EXTERNAL_MODULE_vue_createVNode__("span", {
19803
19948
  "class": resolveClassName('node-text')
19804
- }, [renderNodeSlots(item)]), (_ctx$slots$nodeAppend = (_ctx$slots4 = ctx.slots).nodeAppend) === null || _ctx$slots$nodeAppend === void 0 ? void 0 : _ctx$slots$nodeAppend.call(_ctx$slots4, getScopedSlotData(item))]), showTree && getVirtualLines(item)])]);
19949
+ }, [renderNodeSlots(item, {
19950
+ nodeScoped: ctx.slots.node ? rowAttrScoped !== null && rowAttrScoped !== void 0 ? rowAttrScoped : getAttrScoped() : undefined,
19951
+ defaultScoped: ctx.slots["default"] ? getDefaultScoped() : undefined
19952
+ })]), (_ctx$slots$nodeAppend = (_ctx$slots4 = ctx.slots).nodeAppend) === null || _ctx$slots$nodeAppend === void 0 ? void 0 : _ctx$slots$nodeAppend.call(_ctx$slots4, rowAttrScoped !== null && rowAttrScoped !== void 0 ? rowAttrScoped : getAttrScoped())]), showTree && getVirtualLines(item)])]);
19805
19953
  };
19806
19954
  return {
19807
19955
  renderTreeNode: renderTreeNode,
@@ -20160,7 +20308,6 @@ var use_node_action_this = undefined;
20160
20308
  });
20161
20309
  ;// ../../packages/tree/src/use-search.tsx
20162
20310
 
20163
- var use_search_this = undefined;
20164
20311
  /*
20165
20312
  * Tencent is pleased to support the open source community by making
20166
20313
  * 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community Edition) available.
@@ -20195,15 +20342,11 @@ var use_search_this = undefined;
20195
20342
  var exactMatch = function exactMatch(matchValue, itemValue) {
20196
20343
  return matchValue === itemValue;
20197
20344
  };
20198
- var fuzzyMatch = function fuzzyMatch(matchValue, itemValue) {
20199
- try {
20200
- return new RegExp("".concat(matchValue), 'i').test("".concat(itemValue));
20201
- } catch (_unused) {
20202
- return "".concat(itemValue).toLowerCase().includes("".concat(matchValue).toLowerCase());
20203
- }
20345
+ var fuzzyMatchWithRegex = function fuzzyMatchWithRegex(regex, itemValue) {
20346
+ return regex.test("".concat(itemValue));
20204
20347
  };
20205
- var matchFn = function matchFn(match, args) {
20206
- return Reflect.apply(match, use_search_this, args);
20348
+ var fuzzyMatchIncludes = function fuzzyMatchIncludes(matchValue, itemValue) {
20349
+ return "".concat(itemValue).toLowerCase().includes(matchValue);
20207
20350
  };
20208
20351
  var isSearchDisabled = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20209
20352
  return refSearch.value === undefined || refSearch.value === false;
@@ -20212,10 +20355,9 @@ var use_search_this = undefined;
20212
20355
  if (refSearch.value && _typeof(refSearch.value) === 'object') {
20213
20356
  return refSearch.value;
20214
20357
  }
20215
- var emptyOption = {
20358
+ return {
20216
20359
  value: ''
20217
20360
  };
20218
- return emptyOption;
20219
20361
  });
20220
20362
  var resultType = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20221
20363
  var _searchOption$value$r;
@@ -20225,41 +20367,84 @@ var use_search_this = undefined;
20225
20367
  var _searchOption$value$s;
20226
20368
  return (_searchOption$value$s = searchOption.value.showChildNodes) !== null && _searchOption$value$s !== void 0 ? _searchOption$value$s : false;
20227
20369
  });
20228
- var getSearchValue = function getSearchValue() {
20370
+ /** 只暴露原始检索值,供外部浅层 watch,避免 deep watch 整个 search 对象 */
20371
+ var searchValue = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20229
20372
  var _searchOption$value$v;
20373
+ if (isSearchDisabled.value) {
20374
+ return '';
20375
+ }
20230
20376
  if (isCommonType(refSearch.value)) {
20231
20377
  return refSearch.value;
20232
20378
  }
20233
20379
  return (_searchOption$value$v = searchOption.value.value) !== null && _searchOption$value$v !== void 0 ? _searchOption$value$v : '';
20234
- };
20235
- var searchFn = function searchFn(itemValue, item) {
20380
+ });
20381
+ var isSearchActive = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20382
+ return !isSearchDisabled.value && "".concat(searchValue.value).length > 0;
20383
+ });
20384
+ var isTreeUI = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20385
+ return resultType.value === 'tree';
20386
+ });
20387
+ /**
20388
+ * 为一次检索创建匹配器(模糊匹配只编译一次正则),避免百万节点循环内重复 new RegExp。
20389
+ */
20390
+ var createMatcher = function createMatcher() {
20236
20391
  if (isSearchDisabled.value) {
20237
- return true;
20392
+ return function () {
20393
+ return true;
20394
+ };
20238
20395
  }
20239
- var value = getSearchValue();
20396
+ var value = searchValue.value;
20240
20397
  if ("".concat(value).length === 0) {
20241
- return false;
20398
+ return function () {
20399
+ return false;
20400
+ };
20242
20401
  }
20243
20402
  if (isCommonType(refSearch.value)) {
20244
- return matchFn(fuzzyMatch, [value, itemValue, item]);
20403
+ var _text = "".concat(value);
20404
+ try {
20405
+ var regex = new RegExp(_text, 'i');
20406
+ return function (itemValue) {
20407
+ return fuzzyMatchWithRegex(regex, itemValue);
20408
+ };
20409
+ } catch (_unused) {
20410
+ var lower = _text.toLowerCase();
20411
+ return function (itemValue) {
20412
+ return fuzzyMatchIncludes(lower, itemValue);
20413
+ };
20414
+ }
20245
20415
  }
20246
20416
  var _searchOption$value$m = searchOption.value.match,
20247
20417
  match = _searchOption$value$m === void 0 ? 'fuzzy' : _searchOption$value$m;
20248
- var defaultMatch = match === 'fuzzy' ? fuzzyMatch : exactMatch;
20249
- var matchCallback = typeof match === 'function' ? match : defaultMatch;
20250
- return matchFn(matchCallback, [value, itemValue, item]);
20251
- };
20252
- var isSearchActive = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20253
- if (isSearchDisabled.value) {
20254
- return false;
20418
+ if (typeof match === 'function') {
20419
+ return function (itemValue, item) {
20420
+ return !!match(value, itemValue, item);
20421
+ };
20255
20422
  }
20256
- return "".concat(getSearchValue()).length > 0;
20257
- });
20258
- var isTreeUI = __WEBPACK_EXTERNAL_MODULE_vue_computed__(function () {
20259
- return resultType.value === 'tree';
20260
- });
20423
+ if (match === 'full') {
20424
+ return function (itemValue) {
20425
+ return exactMatch(value, itemValue);
20426
+ };
20427
+ }
20428
+ var text = "".concat(value);
20429
+ try {
20430
+ var _regex = new RegExp(text, 'i');
20431
+ return function (itemValue) {
20432
+ return fuzzyMatchWithRegex(_regex, itemValue);
20433
+ };
20434
+ } catch (_unused2) {
20435
+ var _lower = text.toLowerCase();
20436
+ return function (itemValue) {
20437
+ return fuzzyMatchIncludes(_lower, itemValue);
20438
+ };
20439
+ }
20440
+ };
20441
+ var searchFn = function searchFn(itemValue, item) {
20442
+ return createMatcher()(itemValue, item);
20443
+ };
20261
20444
  return {
20262
20445
  searchFn: searchFn,
20446
+ createMatcher: createMatcher,
20447
+ searchValue: searchValue,
20263
20448
  refSearch: refSearch,
20264
20449
  isSearchActive: isSearchActive,
20265
20450
  isSearchDisabled: isSearchDisabled,
@@ -20549,7 +20734,7 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20549
20734
  isChecked = !!resolveAttr(rawItem, SOURCE_IS_CHECKED, NODE_ATTRIBUTES.IS_CHECKED, checkedDefault);
20550
20735
  }
20551
20736
  }
20552
- var attributes = (_attributes = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_attributes, NODE_ATTRIBUTES.DEPTH, depth), NODE_ATTRIBUTES.INDEX, order), NODE_ATTRIBUTES.UUID, uuid), NODE_ATTRIBUTES.PARENT, parent), NODE_ATTRIBUTES.HAS_CHILD, hasChildren), NODE_ATTRIBUTES.PATH, currentPath), NODE_ATTRIBUTES.IS_ROOT, parent === null), NODE_ATTRIBUTES.ORDER, order), NODE_ATTRIBUTES.IS_SELECTED, isSelected), NODE_ATTRIBUTES.IS_MATCH, !!resolveAttr(rawItem, SOURCE_IS_MATCH, NODE_ATTRIBUTES.IS_MATCH, false)), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_attributes, NODE_ATTRIBUTES.IS_OPEN, isOpened), NODE_ATTRIBUTES.IS_CHECKED, isChecked), NODE_ATTRIBUTES.IS_CACHED, !!resolveAttr(rawItem, SOURCE_IS_CACHED, NODE_ATTRIBUTES.IS_CACHED, false)), NODE_ATTRIBUTES.IS_ASYNC, resolveAttr(rawItem, SOURCE_IS_ASYNC, NODE_ATTRIBUTES.IS_ASYNC, null)), NODE_ATTRIBUTES.IS_LOADING, !!resolveAttr(rawItem, SOURCE_IS_LOADING, NODE_ATTRIBUTES.IS_LOADING, false)), NODE_ATTRIBUTES.IS_INDETERMINATE, false));
20737
+ var attributes = (_attributes = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_attributes, NODE_ATTRIBUTES.DEPTH, depth), NODE_ATTRIBUTES.INDEX, order), NODE_ATTRIBUTES.UUID, uuid), NODE_ATTRIBUTES.PARENT, parent), NODE_ATTRIBUTES.HAS_CHILD, hasChildren), NODE_ATTRIBUTES.PATH, currentPath), NODE_ATTRIBUTES.IS_ROOT, parent === null), NODE_ATTRIBUTES.ORDER, order), NODE_ATTRIBUTES.HAS_NEXT_SIBLING, false), NODE_ATTRIBUTES.IS_SELECTED, isSelected), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_attributes, NODE_ATTRIBUTES.IS_MATCH, !!resolveAttr(rawItem, SOURCE_IS_MATCH, NODE_ATTRIBUTES.IS_MATCH, false)), NODE_ATTRIBUTES.IS_OPEN, isOpened), NODE_ATTRIBUTES.IS_CHECKED, isChecked), NODE_ATTRIBUTES.IS_CACHED, !!resolveAttr(rawItem, SOURCE_IS_CACHED, NODE_ATTRIBUTES.IS_CACHED, false)), NODE_ATTRIBUTES.IS_ASYNC, resolveAttr(rawItem, SOURCE_IS_ASYNC, NODE_ATTRIBUTES.IS_ASYNC, null)), NODE_ATTRIBUTES.IS_LOADING, !!resolveAttr(rawItem, SOURCE_IS_LOADING, NODE_ATTRIBUTES.IS_LOADING, false)), NODE_ATTRIBUTES.IS_INDETERMINATE, false));
20553
20738
  if (isChecked) {
20554
20739
  checkedList.push(rawItem);
20555
20740
  }
@@ -20559,6 +20744,13 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20559
20744
  treeSchema.set(rawItem, attributes);
20560
20745
  nodeMap.set(uuid, rawItem);
20561
20746
  if (parent === null) {
20747
+ if (rootNodes.length) {
20748
+ var prevRoot = rootNodes[rootNodes.length - 1];
20749
+ var prevSchema = treeSchema.get(prevRoot);
20750
+ if (prevSchema) {
20751
+ prevSchema[NODE_ATTRIBUTES.HAS_NEXT_SIBLING] = true;
20752
+ }
20753
+ }
20562
20754
  rootNodes.push(rawItem);
20563
20755
  } else {
20564
20756
  var siblings = childMap.get(parent);
@@ -20566,6 +20758,13 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20566
20758
  siblings = [];
20567
20759
  childMap.set(parent, siblings);
20568
20760
  }
20761
+ if (siblings.length) {
20762
+ var prevSibling = siblings[siblings.length - 1];
20763
+ var _prevSchema = treeSchema.get(prevSibling);
20764
+ if (_prevSchema) {
20765
+ _prevSchema[NODE_ATTRIBUTES.HAS_NEXT_SIBLING] = true;
20766
+ }
20767
+ }
20569
20768
  siblings.push(rawItem);
20570
20769
  }
20571
20770
  outputData.push(rawItem);
@@ -20706,10 +20905,34 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20706
20905
  });
20707
20906
  if (props.selectable) {
20708
20907
  __WEBPACK_EXTERNAL_MODULE_vue_onMounted__(function () {
20908
+ /**
20909
+ * 按「选中 id」监听,而非 props.selected 引用。
20910
+ * 业务侧常见写法 selected={[id]} 每次 computed 都是新数组,按引用 watch 会在每次
20911
+ * content click 后重复 setSelect/autoOpen,放大卡顿。
20912
+ */
20913
+ var _resolveSelectedWatchId = function resolveSelectedWatchId(value) {
20914
+ if (value === undefined || value === null || value === '') {
20915
+ return undefined;
20916
+ }
20917
+ if (Array.isArray(value)) {
20918
+ return _resolveSelectedWatchId(value[0]);
20919
+ }
20920
+ if (typeof value === 'string' || typeof value === 'number') {
20921
+ return value;
20922
+ }
20923
+ if (_typeof(value) === 'object') {
20924
+ var node = value;
20925
+ var key = props.nodeKey;
20926
+ if (key && node[key] !== undefined && node[key] !== null) {
20927
+ return node[key];
20928
+ }
20929
+ return node[NODE_ATTRIBUTES.UUID];
20930
+ }
20931
+ return value;
20932
+ };
20709
20933
  __WEBPACK_EXTERNAL_MODULE_vue_watch__(function () {
20710
- return props.selected;
20934
+ return _resolveSelectedWatchId(props.selected);
20711
20935
  }, function (newData) {
20712
- // console.log('watch selected changed');
20713
20936
  afterSelectWatch.length = 0;
20714
20937
  afterSelectEvents.forEach(function (event) {
20715
20938
  Reflect.apply(event, use_tree_init_this, [newData]);
@@ -20773,32 +20996,82 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20773
20996
  */
20774
20997
 
20775
20998
 
20999
+ /** 单次批量节点刷新超过该阈值时回退全局刷新,避免响应式写爆 */
21000
+ var NODE_UI_REFRESH_GLOBAL_THRESHOLD = 50;
20776
21001
  /**
20777
21002
  * 增量维护树的可见节点列表,避免每次展开都对全量 flatData 做 O(N) filter。
20778
21003
  * 展开/收起复杂度接近 O(受影响的可见子节点数),禁止回退到全表扫描。
21004
+ *
21005
+ * UI 刷新支持按节点粒度 bump,避免自定义插槽时全量可见行重跑。
20779
21006
  */
20780
21007
  /* harmony default export */ const use_visible_nodes = (function (flatData, helpers) {
20781
21008
  var checkNodeIsOpen = helpers.checkNodeIsOpen,
20782
21009
  getChildNodes = helpers.getChildNodes,
20783
21010
  getNodeAttr = helpers.getNodeAttr,
21011
+ getNodeId = helpers.getNodeId,
20784
21012
  getNodeOrder = helpers.getNodeOrder,
20785
21013
  getSchemaVal = helpers.getSchemaVal,
20786
21014
  isNodeOpened = helpers.isNodeOpened;
20787
21015
  var visibleNodes = __WEBPACK_EXTERNAL_MODULE_vue_shallowRef__([]);
21016
+ /** 全量 UI 版本:级联勾选等大批量变更时使用 */
20788
21017
  var uiVersion = __WEBPACK_EXTERNAL_MODULE_vue_shallowRef__(0);
21018
+ /** 任意 UI 刷新的唤醒信号:驱动 Tree 重渲染,具体行是否更新由 nodeUiVersions 决定 */
21019
+ var uiTick = __WEBPACK_EXTERNAL_MODULE_vue_shallowRef__(0);
21020
+ /** 按节点 UI 版本:选中/展开图标等局部变更时只更新对应行 */
21021
+ var nodeUiVersions = __WEBPACK_EXTERNAL_MODULE_vue_reactive__({});
20789
21022
  var uiFlushScheduled = false;
21023
+ var pendingGlobal = false;
21024
+ var pendingNodeIds = new Set();
20790
21025
  var emitListChange = function emitListChange(next) {
20791
21026
  visibleNodes.value = next;
20792
21027
  };
20793
- var scheduleUiRefresh = function scheduleUiRefresh() {
21028
+ var resolveNodeId = function resolveNodeId(node) {
21029
+ var id = getNodeId(node);
21030
+ return id === undefined || id === null ? '' : "".concat(id);
21031
+ };
21032
+ var flushUiRefresh = function flushUiRefresh() {
21033
+ uiFlushScheduled = false;
21034
+ var useGlobal = pendingGlobal || pendingNodeIds.size > NODE_UI_REFRESH_GLOBAL_THRESHOLD;
21035
+ if (useGlobal) {
21036
+ uiVersion.value += 1;
21037
+ } else {
21038
+ pendingNodeIds.forEach(function (id) {
21039
+ if (!id) {
21040
+ return;
21041
+ }
21042
+ nodeUiVersions[id] = (nodeUiVersions[id] || 0) + 1;
21043
+ });
21044
+ }
21045
+ pendingGlobal = false;
21046
+ pendingNodeIds.clear();
21047
+ // 唤醒 Tree → VirtualRender 插槽重跑;未 bump 的 TreeNodeRow 会因 props 不变而跳过
21048
+ uiTick.value += 1;
21049
+ };
21050
+ /**
21051
+ * 调度 UI 刷新:
21052
+ * - 传入 node:仅刷新该行(自定义插槽场景下避免全表 slot 重跑)
21053
+ * - 不传 node:全局刷新
21054
+ */
21055
+ var scheduleUiRefresh = function scheduleUiRefresh(node) {
21056
+ if (node) {
21057
+ var id = resolveNodeId(node);
21058
+ if (id) {
21059
+ pendingNodeIds.add(id);
21060
+ } else {
21061
+ pendingGlobal = true;
21062
+ }
21063
+ } else {
21064
+ pendingGlobal = true;
21065
+ }
20794
21066
  if (uiFlushScheduled) {
20795
21067
  return;
20796
21068
  }
20797
21069
  uiFlushScheduled = true;
20798
- __WEBPACK_EXTERNAL_MODULE_vue_nextTick__(function () {
20799
- uiFlushScheduled = false;
20800
- uiVersion.value += 1;
20801
- });
21070
+ __WEBPACK_EXTERNAL_MODULE_vue_nextTick__(flushUiRefresh);
21071
+ };
21072
+ var getNodeUiVersion = function getNodeUiVersion(node) {
21073
+ var id = resolveNodeId(node);
21074
+ return id ? nodeUiVersions[id] || 0 : 0;
20802
21075
  };
20803
21076
  var rebuildVisibleNodes = function rebuildVisibleNodes(filterFn) {
20804
21077
  var _flatData$rootNodes;
@@ -20817,6 +21090,10 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20817
21090
  }
20818
21091
  emitListChange(next);
20819
21092
  };
21093
+ /** 直接设置可见列表(搜索态按候选集过滤后使用,避免再扫全表) */
21094
+ var setVisibleNodes = function setVisibleNodes(nodes) {
21095
+ emitListChange(nodes.slice());
21096
+ };
20820
21097
  var _collectOpenedBranch = function collectOpenedBranch(node, result) {
20821
21098
  var children = getChildNodes(node);
20822
21099
  for (var i = 0, len = children.length; i < len; i++) {
@@ -20827,6 +21104,57 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20827
21104
  }
20828
21105
  }
20829
21106
  };
21107
+ /** 在 flatData(DFS 序)中按 ORDER 二分定位 */
21108
+ var findFlatIndexByOrder = function findFlatIndexByOrder(targetOrder) {
21109
+ var data = flatData.data;
21110
+ var low = 0;
21111
+ var high = data.length - 1;
21112
+ while (low <= high) {
21113
+ var mid = low + high >> 1;
21114
+ var midOrder = Number(getNodeOrder(data[mid]));
21115
+ if (midOrder === targetOrder) {
21116
+ return mid;
21117
+ }
21118
+ if (midOrder < targetOrder) {
21119
+ low = mid + 1;
21120
+ } else {
21121
+ high = mid - 1;
21122
+ }
21123
+ }
21124
+ return -1;
21125
+ };
21126
+ /**
21127
+ * 收起时清除 flat 连续子孙区间内的 IS_OPEN(O(子树))。
21128
+ * 避免「可见区外仍保持 IS_OPEN」导致再次展开时 collectOpenedBranch 一次插入巨量子树。
21129
+ */
21130
+ var resetFlatDescendantOpenState = function resetFlatDescendantOpenState(node) {
21131
+ var _getNodeAttr;
21132
+ var nodeOrder = Number(getNodeOrder(node));
21133
+ var nodeDepth = Number((_getNodeAttr = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr !== void 0 ? _getNodeAttr : 0);
21134
+ if (Number.isNaN(nodeOrder)) {
21135
+ return;
21136
+ }
21137
+ var start = findFlatIndexByOrder(nodeOrder) + 1;
21138
+ if (start <= 0) {
21139
+ return;
21140
+ }
21141
+ var data = flatData.data;
21142
+ for (var i = start, len = data.length; i < len; i++) {
21143
+ var _getNodeAttr2;
21144
+ var depth = Number((_getNodeAttr2 = getNodeAttr(data[i], NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr2 !== void 0 ? _getNodeAttr2 : -1);
21145
+ if (depth <= nodeDepth) {
21146
+ break;
21147
+ }
21148
+ var schema = getSchemaVal(data[i]);
21149
+ if (!(schema !== null && schema !== void 0 && schema[NODE_ATTRIBUTES.IS_OPEN])) {
21150
+ continue;
21151
+ }
21152
+ schema[NODE_ATTRIBUTES.IS_OPEN] = false;
21153
+ if ((flatData.openCount || 0) > 0) {
21154
+ flatData.openCount -= 1;
21155
+ }
21156
+ }
21157
+ };
20830
21158
  /** 仅在可见列表内线性查找,O(V),禁止回退扫 flat 全表 */
20831
21159
  var findVisibleIndexLinear = function findVisibleIndexLinear(node) {
20832
21160
  var list = visibleNodes.value;
@@ -20883,65 +21211,79 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20883
21211
  }
20884
21212
  };
20885
21213
  /**
20886
- * 展开节点:在可见列表中插入直接子节点,以及已展开子树。
21214
+ * 展开节点:默认只插入直接子节点。
21215
+ * 若直接子节点自身已展开,再按需带上其已展开子树;
21216
+ * 配合 collapse 时清除 flat 子孙 IS_OPEN,避免一次插入数十万节点。
20887
21217
  */
20888
21218
  var expandVisibleNode = function expandVisibleNode(node) {
20889
- var _getNodeAttr;
21219
+ var _getNodeAttr3;
20890
21220
  var index = findVisibleIndex(node);
20891
21221
  if (index < 0) {
20892
- // 不回退全表 rebuild(百万节点会卡 ~1s),只刷新当前行展开图标
20893
- scheduleUiRefresh();
21222
+ scheduleUiRefresh(node);
20894
21223
  return;
20895
21224
  }
20896
21225
  var list = visibleNodes.value;
20897
- // 已有后代可见则认为已展开,只刷新图标
20898
- var nodeDepth = Number((_getNodeAttr = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr !== void 0 ? _getNodeAttr : 0);
21226
+ var nodeDepth = Number((_getNodeAttr3 = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr3 !== void 0 ? _getNodeAttr3 : 0);
20899
21227
  var next = list[index + 1];
20900
21228
  if (next) {
20901
- var _getNodeAttr2;
20902
- var nextDepth = Number((_getNodeAttr2 = getNodeAttr(next, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr2 !== void 0 ? _getNodeAttr2 : -1);
21229
+ var _getNodeAttr4;
21230
+ var nextDepth = Number((_getNodeAttr4 = getNodeAttr(next, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr4 !== void 0 ? _getNodeAttr4 : -1);
20903
21231
  if (nextDepth > nodeDepth) {
20904
- scheduleUiRefresh();
21232
+ scheduleUiRefresh(node);
20905
21233
  return;
20906
21234
  }
20907
21235
  }
20908
- var insertNodes = [];
20909
- _collectOpenedBranch(node, insertNodes);
20910
- if (!insertNodes.length) {
20911
- scheduleUiRefresh();
21236
+ var children = getChildNodes(node);
21237
+ if (!children.length) {
21238
+ scheduleUiRefresh(node);
20912
21239
  return;
20913
21240
  }
21241
+ // 只展开一层:已打开的子节点再带上其子树(收起时已清子孙 IS_OPEN,通常不会很大)
21242
+ var insertNodes = [];
21243
+ for (var i = 0, len = children.length; i < len; i++) {
21244
+ var child = children[i];
21245
+ insertNodes.push(child);
21246
+ if (isNodeOpened(child)) {
21247
+ _collectOpenedBranch(child, insertNodes);
21248
+ }
21249
+ }
20914
21250
  emitListChange(list.slice(0, index + 1).concat(insertNodes, list.slice(index + 1)));
21251
+ scheduleUiRefresh(node);
20915
21252
  };
20916
21253
  /**
20917
21254
  * 收起节点:
20918
- * 1) 只关闭「可见后代」中的 IS_OPEN(不必扫 flat 全量子树)
21255
+ * 1) 清除 flat 子孙 IS_OPEN(防止再次展开时拖入巨量子树)
20919
21256
  * 2) 从可见列表移除该区间
20920
21257
  */
20921
21258
  var collapseVisibleNode = function collapseVisibleNode(node) {
20922
- var _getNodeAttr3;
21259
+ var _getNodeAttr5;
20923
21260
  var index = findVisibleIndex(node);
20924
21261
  if (index < 0) {
20925
- scheduleUiRefresh();
21262
+ // 即使不在可见列表,也清掉 flat 子孙 open,保持状态一致
21263
+ resetFlatDescendantOpenState(node);
21264
+ scheduleUiRefresh(node);
20926
21265
  return;
20927
21266
  }
20928
21267
  var list = visibleNodes.value;
20929
- var nodeDepth = Number((_getNodeAttr3 = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr3 !== void 0 ? _getNodeAttr3 : 0);
21268
+ var nodeDepth = Number((_getNodeAttr5 = getNodeAttr(node, NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr5 !== void 0 ? _getNodeAttr5 : 0);
20930
21269
  var end = index + 1;
20931
21270
  while (end < list.length) {
20932
- var _getNodeAttr4;
20933
- var depth = Number((_getNodeAttr4 = getNodeAttr(list[end], NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr4 !== void 0 ? _getNodeAttr4 : -1);
21271
+ var _getNodeAttr6;
21272
+ var depth = Number((_getNodeAttr6 = getNodeAttr(list[end], NODE_ATTRIBUTES.DEPTH)) !== null && _getNodeAttr6 !== void 0 ? _getNodeAttr6 : -1);
20934
21273
  if (depth <= nodeDepth) {
20935
21274
  break;
20936
21275
  }
20937
21276
  end += 1;
20938
21277
  }
21278
+ // 先清 flat 子孙,再改可见列表(closeOpenedInRange 对已关闭节点是 no-op)
21279
+ resetFlatDescendantOpenState(node);
20939
21280
  if (end === index + 1) {
20940
- scheduleUiRefresh();
21281
+ scheduleUiRefresh(node);
20941
21282
  return;
20942
21283
  }
20943
21284
  closeOpenedInRange(list, index + 1, end);
20944
21285
  emitListChange(list.slice(0, index + 1).concat(list.slice(end)));
21286
+ scheduleUiRefresh(node);
20945
21287
  };
20946
21288
  var syncNodeOpenState = function syncNodeOpenState(node, isOpen) {
20947
21289
  if (isOpen) {
@@ -20954,7 +21296,11 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20954
21296
  return {
20955
21297
  visibleNodes: visibleNodes,
20956
21298
  uiVersion: uiVersion,
21299
+ uiTick: uiTick,
21300
+ nodeUiVersions: nodeUiVersions,
21301
+ getNodeUiVersion: getNodeUiVersion,
20957
21302
  rebuildVisibleNodes: rebuildVisibleNodes,
21303
+ setVisibleNodes: setVisibleNodes,
20958
21304
  expandVisibleNode: expandVisibleNode,
20959
21305
  collapseVisibleNode: collapseVisibleNode,
20960
21306
  syncNodeOpenState: syncNodeOpenState,
@@ -20963,7 +21309,6 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
20963
21309
  });
20964
21310
  ;// ../../packages/tree/src/tree.tsx
20965
21311
 
20966
-
20967
21312
  /*
20968
21313
  * Tencent is pleased to support the open source community by making
20969
21314
  * 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community Edition) available.
@@ -21006,6 +21351,7 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21006
21351
 
21007
21352
 
21008
21353
 
21354
+
21009
21355
  /* harmony default export */ const tree = (__WEBPACK_EXTERNAL_MODULE_vue_defineComponent__({
21010
21356
  name: 'Tree',
21011
21357
  props: treeProps,
@@ -21034,22 +21380,36 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21034
21380
  getIntersectionResponse = _useNodeAttribute.getIntersectionResponse,
21035
21381
  getChildNodes = _useNodeAttribute.getChildNodes,
21036
21382
  getNodePath = _useNodeAttribute.getNodePath,
21037
- getSchemaVal = _useNodeAttribute.getSchemaVal;
21383
+ getSchemaVal = _useNodeAttribute.getSchemaVal,
21384
+ setNodeAttr = _useNodeAttribute.setNodeAttr;
21038
21385
  var _useSearch = use_search(props),
21039
- searchFn = _useSearch.searchFn,
21386
+ createMatcher = _useSearch.createMatcher,
21387
+ searchValue = _useSearch.searchValue,
21040
21388
  isSearchActive = _useSearch.isSearchActive,
21041
- refSearch = _useSearch.refSearch,
21042
- isSearchDisabled = _useSearch.isSearchDisabled,
21043
21389
  isTreeUI = _useSearch.isTreeUI,
21044
21390
  resultType = _useSearch.resultType,
21045
21391
  showChildNodes = _useSearch.showChildNodes;
21046
- var matchedNodeIds = __WEBPACK_EXTERNAL_MODULE_vue_reactive__(new Set());
21047
- var visibleNodeIds = __WEBPACK_EXTERNAL_MODULE_vue_reactive__(new Set());
21392
+ // 不可用 reactive(Set):百万次 add/clear 会反复触发依赖,导致检索「连续刷新」
21393
+ var matchedNodeIds = new Set();
21394
+ var visibleNodeIds = new Set();
21395
+ /** 搜索候选节点(DFS 序),展开/收起时只在此集合上过滤,O(命中集) */
21396
+ var searchCandidateNodes = [];
21048
21397
  var searchOriginalOpenState = new Map();
21398
+ var getChildNodesForVisible = function getChildNodesForVisible(node) {
21399
+ var children = getChildNodes(node);
21400
+ if (!isSearchActive.value) {
21401
+ return children;
21402
+ }
21403
+ // 搜索态只插入检索可见集内的子节点,保证展开/收起增量正确
21404
+ return children.filter(function (child) {
21405
+ return visibleNodeIds.has("".concat(getNodeId(child)));
21406
+ });
21407
+ };
21049
21408
  var _useVisibleNodes = use_visible_nodes(flatData, {
21050
21409
  checkNodeIsOpen: checkNodeIsOpen,
21051
- getChildNodes: getChildNodes,
21410
+ getChildNodes: getChildNodesForVisible,
21052
21411
  getNodeAttr: getNodeAttr,
21412
+ getNodeId: getNodeId,
21053
21413
  getNodePath: getNodePath,
21054
21414
  getNodeOrder: function getNodeOrder(node) {
21055
21415
  var _getNodeAttr;
@@ -21060,32 +21420,57 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21060
21420
  }),
21061
21421
  renderData = _useVisibleNodes.visibleNodes,
21062
21422
  uiVersion = _useVisibleNodes.uiVersion,
21423
+ uiTick = _useVisibleNodes.uiTick,
21424
+ nodeUiVersions = _useVisibleNodes.nodeUiVersions,
21063
21425
  rebuildVisibleNodes = _useVisibleNodes.rebuildVisibleNodes,
21426
+ setVisibleNodes = _useVisibleNodes.setVisibleNodes,
21064
21427
  syncNodeOpenStateRaw = _useVisibleNodes.syncNodeOpenState,
21065
21428
  scheduleUiRefresh = _useVisibleNodes.scheduleUiRefresh;
21066
- var filterFn = function filterFn(item) {
21067
- if (isSearchActive.value) {
21068
- return visibleNodeIds.has("".concat(getNodeId(item)));
21429
+ var isSearchTreeNodeVisible = function isSearchTreeNodeVisible(item) {
21430
+ if (!visibleNodeIds.has("".concat(getNodeId(item)))) {
21431
+ return false;
21069
21432
  }
21070
- return checkNodeIsOpen(item);
21433
+ var parent = getParentNode(item);
21434
+ while (parent) {
21435
+ if (!isNodeOpened(parent)) {
21436
+ return false;
21437
+ }
21438
+ parent = getParentNode(parent);
21439
+ }
21440
+ return true;
21441
+ };
21442
+ var rebuildSearchVisibleList = function rebuildSearchVisibleList() {
21443
+ if (!isTreeUI.value) {
21444
+ setVisibleNodes(searchCandidateNodes);
21445
+ return;
21446
+ }
21447
+ var next = [];
21448
+ for (var i = 0, len = searchCandidateNodes.length; i < len; i++) {
21449
+ var item = searchCandidateNodes[i];
21450
+ if (isSearchTreeNodeVisible(item)) {
21451
+ next.push(item);
21452
+ }
21453
+ }
21454
+ setVisibleNodes(next);
21071
21455
  };
21072
21456
  /**
21073
- * 搜索态下可见集由 matched/visibleNodeIds 决定,不能按父子关系增量插入;
21074
- * 非搜索态走 O(子树) 增量更新。
21457
+ * 搜索 list 模式:展开不影响可见集。
21458
+ * 其它情况走增量 expand/collapse(搜索 tree 下 getChildNodes 已按候选集过滤)。
21075
21459
  */
21076
21460
  var syncNodeOpenState = function syncNodeOpenState(node, isOpen) {
21077
- if (isSearchActive.value) {
21078
- rebuildVisibleNodes(filterFn);
21461
+ if (isSearchActive.value && !isTreeUI.value) {
21462
+ scheduleUiRefresh(node);
21079
21463
  return;
21080
21464
  }
21081
21465
  syncNodeOpenStateRaw(node, isOpen);
21082
21466
  };
21083
- flatData.notifySchemaChange = function (_node, attr) {
21084
- // IS_OPEN 由 syncNodeOpenState 增量维护可见列表
21467
+ flatData.notifySchemaChange = function (node, attr) {
21468
+ // IS_OPEN 由 syncNodeOpenState 增量维护可见列表,并按节点刷新图标
21085
21469
  if (attr === NODE_ATTRIBUTES.IS_OPEN) {
21086
21470
  return;
21087
21471
  }
21088
- scheduleUiRefresh();
21472
+ // 选中/勾选等:只刷新变更节点,避免自定义插槽全量重跑
21473
+ scheduleUiRefresh(node);
21089
21474
  };
21090
21475
  var getRenderNodeId = function getRenderNodeId(node) {
21091
21476
  return "".concat(getNodeId(node));
@@ -21095,17 +21480,44 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21095
21480
  if (!searchOriginalOpenState.has(nodeId)) {
21096
21481
  searchOriginalOpenState.set(nodeId, isNodeOpened(node));
21097
21482
  }
21098
- setNodeAttribute(node, NODE_ATTRIBUTES.IS_OPEN, true, false);
21483
+ setNodeAttr(node, NODE_ATTRIBUTES.IS_OPEN, true, undefined, {
21484
+ silent: true
21485
+ });
21099
21486
  };
21100
21487
  var restoreSearchOpenState = function restoreSearchOpenState() {
21101
21488
  searchOriginalOpenState.forEach(function (isOpen, nodeId) {
21102
21489
  var node = getNodeById(nodeId);
21103
21490
  if (node) {
21104
- setNodeAttribute(node, NODE_ATTRIBUTES.IS_OPEN, isOpen, false);
21491
+ setNodeAttr(node, NODE_ATTRIBUTES.IS_OPEN, isOpen, undefined, {
21492
+ silent: true
21493
+ });
21105
21494
  }
21106
21495
  });
21107
21496
  searchOriginalOpenState.clear();
21108
21497
  };
21498
+ /** 校准 openCount,避免搜索展开/收起后计数漂移导致可见列表走错快捷路径 */
21499
+ var syncOpenCount = function syncOpenCount() {
21500
+ var count = 0;
21501
+ var data = flatData.data;
21502
+ for (var i = 0, len = data.length; i < len; i++) {
21503
+ var _getSchemaVal;
21504
+ if ((_getSchemaVal = getSchemaVal(data[i])) !== null && _getSchemaVal !== void 0 && _getSchemaVal[NODE_ATTRIBUTES.IS_OPEN]) {
21505
+ count += 1;
21506
+ }
21507
+ }
21508
+ flatData.openCount = count;
21509
+ };
21510
+ var clearMatchedFlags = function clearMatchedFlags() {
21511
+ matchedNodeIds.forEach(function (nodeId) {
21512
+ var node = getNodeById(nodeId);
21513
+ if (node) {
21514
+ setNodeAttr(node, NODE_ATTRIBUTES.IS_MATCH, false, undefined, {
21515
+ silent: true
21516
+ });
21517
+ }
21518
+ });
21519
+ matchedNodeIds.clear();
21520
+ };
21109
21521
  var addAncestorNodes = function addAncestorNodes(node) {
21110
21522
  var parent = getParentNode(node);
21111
21523
  while (parent) {
@@ -21116,12 +21528,16 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21116
21528
  }
21117
21529
  };
21118
21530
  var _addDescendantNodes = function addDescendantNodes(node) {
21119
- var _flatData$childMap$ge, _flatData$childMap;
21120
- var children = (_flatData$childMap$ge = (_flatData$childMap = flatData.childMap) === null || _flatData$childMap === void 0 ? void 0 : _flatData$childMap.get(node)) !== null && _flatData$childMap$ge !== void 0 ? _flatData$childMap$ge : [];
21121
- children.forEach(function (child) {
21531
+ var children = getChildNodes(node);
21532
+ for (var i = 0, len = children.length; i < len; i++) {
21533
+ var child = children[i];
21122
21534
  visibleNodeIds.add(getRenderNodeId(child));
21535
+ // showChildNodes:默认展开有子节点的路径,深层结果可直接可见;用户仍可手动收起
21536
+ if (hasChildNode(child)) {
21537
+ setSearchNodeOpen(child);
21538
+ }
21123
21539
  _addDescendantNodes(child);
21124
- });
21540
+ }
21125
21541
  };
21126
21542
  var _useIntersectionObser = use_intersection_observer(props),
21127
21543
  getLastVisibleElement = _useIntersectionObser.getLastVisibleElement,
@@ -21204,66 +21620,77 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21204
21620
  setNodeAction = _useNodeAction.setNodeAction,
21205
21621
  setSelect = _useNodeAction.setSelect,
21206
21622
  asyncNodeClick = _useNodeAction.asyncNodeClick,
21207
- setNodeAttribute = _useNodeAction.setNodeAttribute,
21208
21623
  applyCheckedChange = _useNodeAction.applyCheckedChange,
21209
21624
  emitCheckedChange = _useNodeAction.emitCheckedChange,
21210
21625
  rebuildCheckedSetsFromList = _useNodeAction.rebuildCheckedSetsFromList,
21211
21626
  clearAllCheckedState = _useNodeAction.clearAllCheckedState;
21212
21627
  // 数据重建完成后同步勾选索引与可见列表(保证读到最新 schema)
21213
- var syncAfterRebuild = function syncAfterRebuild() {
21214
- rebuildCheckedSetsFromList(flatData.checkedList || []);
21215
- rebuildVisibleNodes(isSearchActive.value ? filterFn : undefined);
21216
- };
21217
- onAfterRebuild(syncAfterRebuild);
21218
- __WEBPACK_EXTERNAL_MODULE_vue_watch__(function () {
21219
- return flatData.data;
21220
- }, syncAfterRebuild);
21221
- var handleSearch = __WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_shared_edbdfb03_debounce__(120, function () {
21222
- // 非搜索态:禁止扫全表写 IS_MATCH(百万节点首屏会卡死)
21628
+ var runSearch = function runSearch() {
21629
+ restoreSearchOpenState();
21630
+ clearMatchedFlags();
21631
+ visibleNodeIds.clear();
21632
+ searchCandidateNodes = [];
21633
+ // 非搜索态:只恢复展开并重建可见列表,禁止扫全表写 IS_MATCH
21223
21634
  if (!isSearchActive.value) {
21224
- if (searchOriginalOpenState.size) {
21225
- restoreSearchOpenState();
21226
- }
21227
- if (matchedNodeIds.size) {
21228
- matchedNodeIds.forEach(function (nodeId) {
21229
- var node = getNodeById(nodeId);
21230
- if (node) {
21231
- setNodeAttribute(node, NODE_ATTRIBUTES.IS_MATCH, false, false);
21232
- }
21233
- });
21234
- matchedNodeIds.clear();
21235
- }
21236
- visibleNodeIds.clear();
21635
+ syncOpenCount();
21237
21636
  rebuildVisibleNodes();
21637
+ scheduleUiRefresh();
21238
21638
  return;
21239
21639
  }
21240
- restoreSearchOpenState();
21241
- matchedNodeIds.clear();
21242
- visibleNodeIds.clear();
21243
- flatData.data.forEach(function (item) {
21244
- var isMatch = !isSearchDisabled.value && searchFn(getLabel(item, props), item);
21245
- var nodeId = getRenderNodeId(item);
21246
- if (isMatch) {
21247
- matchedNodeIds.add(nodeId);
21248
- visibleNodeIds.add(nodeId);
21249
- }
21250
- setNodeAttribute(item, [NODE_ATTRIBUTES.IS_MATCH, NODE_ATTRIBUTES.IS_OPEN], [isMatch, isNodeOpened(item)], false);
21251
- });
21252
- flatData.data.forEach(function (item) {
21253
- if (!matchedNodeIds.has(getRenderNodeId(item))) {
21254
- return;
21640
+ var matcher = createMatcher();
21641
+ var data = flatData.data;
21642
+ var matchedNodes = [];
21643
+ for (var i = 0, len = data.length; i < len; i++) {
21644
+ var item = data[i];
21645
+ if (!matcher(getLabel(item, props), item)) {
21646
+ continue;
21255
21647
  }
21648
+ var nodeId = getRenderNodeId(item);
21649
+ matchedNodeIds.add(nodeId);
21650
+ visibleNodeIds.add(nodeId);
21651
+ matchedNodes.push(item);
21652
+ // 仅给命中节点打标,禁止全表 setAttribute
21653
+ setNodeAttr(item, NODE_ATTRIBUTES.IS_MATCH, true, undefined, {
21654
+ silent: true
21655
+ });
21656
+ }
21657
+ for (var _i = 0, _len = matchedNodes.length; _i < _len; _i++) {
21658
+ var _item = matchedNodes[_i];
21256
21659
  if (resultType.value === 'tree') {
21257
- addAncestorNodes(item);
21660
+ addAncestorNodes(_item);
21258
21661
  }
21259
21662
  if (showChildNodes.value) {
21260
- setSearchNodeOpen(item);
21261
- _addDescendantNodes(item);
21663
+ setSearchNodeOpen(_item);
21664
+ _addDescendantNodes(_item);
21262
21665
  }
21263
- });
21264
- rebuildVisibleNodes(filterFn);
21265
- });
21266
- __WEBPACK_EXTERNAL_MODULE_vue_watch__([refSearch, resultType, showChildNodes, isSearchActive], function () {
21666
+ }
21667
+ // 按 DFS 序收集候选集,后续展开/收起只扫候选集
21668
+ for (var _i2 = 0, _len2 = data.length; _i2 < _len2; _i2++) {
21669
+ var _item2 = data[_i2];
21670
+ if (visibleNodeIds.has(getRenderNodeId(_item2))) {
21671
+ searchCandidateNodes.push(_item2);
21672
+ }
21673
+ }
21674
+ rebuildSearchVisibleList();
21675
+ scheduleUiRefresh();
21676
+ };
21677
+ var syncAfterRebuild = function syncAfterRebuild() {
21678
+ rebuildCheckedSetsFromList(flatData.checkedList || []);
21679
+ if (isSearchActive.value) {
21680
+ runSearch();
21681
+ return;
21682
+ }
21683
+ rebuildVisibleNodes();
21684
+ };
21685
+ onAfterRebuild(syncAfterRebuild);
21686
+ __WEBPACK_EXTERNAL_MODULE_vue_watch__(function () {
21687
+ return flatData.data;
21688
+ }, syncAfterRebuild);
21689
+ var handleSearch = __WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_shared_edbdfb03_debounce__(120, runSearch);
21690
+ // 只浅监听检索值 / 展示模式,避免 deep watch search 对象在赋值时连环触发
21691
+ __WEBPACK_EXTERNAL_MODULE_vue_watch__(function () {
21692
+ return [searchValue.value, resultType.value, showChildNodes.value];
21693
+ }, function () {
21267
21694
  handleSearch();
21268
21695
  }, {
21269
21696
  immediate: true
@@ -21316,8 +21743,9 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21316
21743
  emitCheckedChange();
21317
21744
  }
21318
21745
  };
21746
+ // 同步受控 selected:勿再抛 node-selected,避免与 content click 形成「emit → 改 props → 再 setSelect/emit」环
21319
21747
  onSelected(function (newData) {
21320
- setSelect(newData, true, props.autoOpenParentNode, true);
21748
+ setSelect(newData, true, props.autoOpenParentNode, false);
21321
21749
  });
21322
21750
  __WEBPACK_EXTERNAL_MODULE_vue_watch__(function () {
21323
21751
  return props.data;
@@ -21419,6 +21847,55 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21419
21847
  var triggerEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
21420
21848
  setChecked(getNodeById(id), checked, triggerEvent);
21421
21849
  };
21850
+ /**
21851
+ * 收起全部节点。
21852
+ * 直接批量清 schema.IS_OPEN,避免逐节点 setOpen 触发百万次增量更新。
21853
+ */
21854
+ var collapseAll = function collapseAll() {
21855
+ var data = flatData.data;
21856
+ for (var i = 0, len = data.length; i < len; i++) {
21857
+ var schema = getSchemaVal(data[i]);
21858
+ if (schema !== null && schema !== void 0 && schema[NODE_ATTRIBUTES.IS_OPEN]) {
21859
+ schema[NODE_ATTRIBUTES.IS_OPEN] = false;
21860
+ }
21861
+ }
21862
+ flatData.openCount = 0;
21863
+ if (isSearchActive.value) {
21864
+ rebuildSearchVisibleList();
21865
+ } else {
21866
+ rebuildVisibleNodes();
21867
+ }
21868
+ scheduleUiRefresh();
21869
+ };
21870
+ /**
21871
+ * 展开全部节点(openAllNodes)。
21872
+ * 批量写 IS_OPEN 后一次性重建可见列表。
21873
+ */
21874
+ var expandAllNodes = function expandAllNodes() {
21875
+ var data = flatData.data;
21876
+ var openCount = 0;
21877
+ for (var i = 0, len = data.length; i < len; i++) {
21878
+ var node = data[i];
21879
+ if (!hasChildNode(node)) {
21880
+ continue;
21881
+ }
21882
+ var schema = getSchemaVal(node);
21883
+ if (!schema) {
21884
+ continue;
21885
+ }
21886
+ if (!schema[NODE_ATTRIBUTES.IS_OPEN]) {
21887
+ schema[NODE_ATTRIBUTES.IS_OPEN] = true;
21888
+ }
21889
+ openCount += 1;
21890
+ }
21891
+ flatData.openCount = openCount;
21892
+ if (isSearchActive.value) {
21893
+ rebuildSearchVisibleList();
21894
+ } else {
21895
+ rebuildVisibleNodes();
21896
+ }
21897
+ scheduleUiRefresh();
21898
+ };
21422
21899
  ctx.expose({
21423
21900
  handleTreeNodeClick: handleTreeNodeClick,
21424
21901
  isNodeChecked: isNodeChecked,
@@ -21437,7 +21914,10 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21437
21914
  getData: getData,
21438
21915
  reset: reset,
21439
21916
  getNodeAttr: getNodeAttr,
21440
- getParentNode: getParentNode
21917
+ getParentNode: getParentNode,
21918
+ collapseAll: collapseAll,
21919
+ expandAll: expandAllNodes,
21920
+ openAllNodes: expandAllNodes
21441
21921
  });
21442
21922
  var _useEmpty = use_empty(props),
21443
21923
  renderEmpty = _useEmpty.renderEmpty;
@@ -21450,8 +21930,18 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21450
21930
  var renderTreeContent = function renderTreeContent(scopedData) {
21451
21931
  var _ctx$slots$empty, _ctx$slots$empty2, _ctx$slots;
21452
21932
  if (scopedData.length) {
21933
+ var showTree = !isSearchActive.value || isTreeUI.value;
21934
+ var globalVersion = uiVersion.value;
21453
21935
  return scopedData.map(function (d) {
21454
- return renderTreeNode(d, !isSearchActive.value || isTreeUI.value);
21936
+ var id = "".concat(getNodeId(d));
21937
+ return __WEBPACK_EXTERNAL_MODULE_vue_createVNode__(tree_node_row, {
21938
+ "key": id,
21939
+ "item": d,
21940
+ "showTree": showTree,
21941
+ "version": nodeUiVersions[id] || 0,
21942
+ "globalVersion": globalVersion,
21943
+ "renderFn": renderTreeNode
21944
+ }, null);
21455
21945
  });
21456
21946
  }
21457
21947
  var emptyType = isSearchActive.value ? 'search-empty' : 'empty';
@@ -21487,8 +21977,8 @@ var SOURCE_IS_LOADING = NODE_SOURCE_ATTRS[NODE_ATTRIBUTES.IS_LOADING];
21487
21977
  var _usePrefix = __WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_config_provider_fe8577a3_usePrefix__(),
21488
21978
  resolveClassName = _usePrefix.resolveClassName;
21489
21979
  return function () {
21490
- // 依赖 uiVersion,确保 checkbox/selected 等 schema 变更能触发重渲染
21491
- void uiVersion.value;
21980
+ // uiTick:节点级刷新时唤醒 Tree;具体哪些行更新由 TreeNodeRow 的 version 决定
21981
+ void uiTick.value;
21492
21982
  return __WEBPACK_EXTERNAL_MODULE_vue_createVNode__(__WEBPACK_EXTERNAL_MODULE_bkui_vue_lib_virtual_render_927587a8_default__, {
21493
21983
  "ref": root,
21494
21984
  "style": getTreeStyle(null, props),