@splicetree/adapter-vue 3.0.0 → 3.0.2

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Ref, ShallowRef, WritableComputedRef } from "vue";
1
+ import { ComputedRef, Ref, ShallowRef, WritableComputedRef } from "vue";
2
2
  import { SpliceTreeData, SpliceTreeData as SpliceTreeData$1, SpliceTreeInstance, SpliceTreeInstance as SpliceTreeInstance$1, SpliceTreeNode, SpliceTreeNode as SpliceTreeNode$1, UseSpliceTreeOptions, UseSpliceTreeOptions as UseSpliceTreeOptions$1 } from "@splicetree/core";
3
3
 
4
4
  //#region src/index.d.ts
@@ -8,12 +8,15 @@ interface UseSpliceTreeReturn<T extends SpliceTreeData$1 = SpliceTreeData$1> ext
8
8
  /** 原始 Set 引用(当启用 selectable 插件时存在) */
9
9
  selectedKeysSet?: Set<string>;
10
10
  }
11
+ type UseSpliceTreeVueOptions<T extends SpliceTreeData$1 = SpliceTreeData$1> = UseSpliceTreeOptions$1<T> & {
12
+ expandedKeys?: ComputedRef<string | string[]> | Ref<string | string[]> | WritableComputedRef<string | string[]>;
13
+ };
11
14
  /**
12
15
  * Vue 3 适配器
13
16
  * - 以 shallowRef 暴露 items,使其在核心派发 visibility 事件时刷新
14
17
  * - 保留核心 API 的完整返回(展开/收起/移动等方法)
15
18
  * - 适用于任意自定义渲染逻辑与组件绑定
16
19
  */
17
- declare function useSpliceTree<T extends SpliceTreeData$1 = SpliceTreeData$1>(data: Ref<T[]> | T[] | WritableComputedRef<T[]>, options?: UseSpliceTreeOptions$1<T>): UseSpliceTreeReturn<T>;
20
+ declare function useSpliceTree<T extends SpliceTreeData$1 = SpliceTreeData$1>(data: T[] | Ref<T[]> | ComputedRef<T[]> | WritableComputedRef<T[]>, options?: UseSpliceTreeVueOptions<T>): UseSpliceTreeReturn<T>;
18
21
  //#endregion
19
- export { type SpliceTreeData, type SpliceTreeInstance, type SpliceTreeNode, type UseSpliceTreeOptions, UseSpliceTreeReturn, useSpliceTree };
22
+ export { type SpliceTreeData, type SpliceTreeInstance, type SpliceTreeNode, type UseSpliceTreeOptions, UseSpliceTreeReturn, UseSpliceTreeVueOptions, useSpliceTree };
package/dist/index.js CHANGED
@@ -318,6 +318,36 @@ function moveNode(ctx, id, newParentId, beforeId) {
318
318
  setLevelRecursively(node, ctx.childrenCache, node.level);
319
319
  ctx.notify();
320
320
  }
321
+ function removeNodes(ctx, ids) {
322
+ const list = Array.isArray(ids) ? ids : [ids];
323
+ const toRemove = /* @__PURE__ */ new Set();
324
+ const collect = (id) => {
325
+ if (toRemove.has(id)) return;
326
+ toRemove.add(id);
327
+ const children = ctx.childrenCache.get(id) ?? [];
328
+ for (const c of children) collect(c.id);
329
+ };
330
+ for (const id of list) if (ctx.map.has(id)) collect(id);
331
+ for (const id of toRemove) {
332
+ const parent = ctx.parentCache.get(id);
333
+ if (parent) {
334
+ const arr = ctx.childrenCache.get(parent.id) ?? [];
335
+ const idx = arr.findIndex((n) => n.id === id);
336
+ if (idx >= 0) arr.splice(idx, 1);
337
+ } else {
338
+ const idx = ctx.roots.findIndex((n) => n.id === id);
339
+ if (idx >= 0) ctx.roots.splice(idx, 1);
340
+ }
341
+ }
342
+ for (const id of toRemove) {
343
+ ctx.childrenCache.delete(id);
344
+ ctx.parentCache.delete(id);
345
+ ctx.map.delete(id);
346
+ ctx.expandedKeys.delete(id);
347
+ }
348
+ for (const r of ctx.roots) setLevelRecursively(r, ctx.childrenCache, 0);
349
+ ctx.notify();
350
+ }
321
351
  /**
322
352
  * 创建 SpliceTree 树实例
323
353
  * - 构建缓存结构
@@ -325,6 +355,7 @@ function moveNode(ctx, id, newParentId, beforeId) {
325
355
  * - 提供插件扩展点(setup/extendNode)
326
356
  */
327
357
  function createSpliceTree(data, options = {}) {
358
+ let pluginCtx;
328
359
  const cfg = options.configuration ?? {};
329
360
  const keyField = cfg.keyField ?? "id";
330
361
  const parentField = cfg.parentField ?? "parent";
@@ -409,6 +440,18 @@ function createSpliceTree(data, options = {}) {
409
440
  notify: emitVisibility
410
441
  }, id, newParentId, beforeId);
411
442
  },
443
+ remove(ids) {
444
+ removeNodes({
445
+ map,
446
+ tree,
447
+ roots,
448
+ keyField,
449
+ parentCache,
450
+ childrenCache,
451
+ expandedKeys,
452
+ notify: emitVisibility
453
+ }, ids);
454
+ },
412
455
  syncData(next) {
413
456
  tree.data = next;
414
457
  const built = buildTree(next, keyField, parentField, expandedKeys);
@@ -423,13 +466,21 @@ function createSpliceTree(data, options = {}) {
423
466
  });
424
467
  for (const id of toDelete) expandedKeys.delete(id);
425
468
  applyNodeExtensions();
469
+ pluginCtx.roots = roots;
470
+ pluginCtx.map = map;
471
+ pluginCtx.parentCache = parentCache;
472
+ pluginCtx.childrenCache = childrenCache;
426
473
  emitVisibility();
427
474
  }
428
475
  };
429
- const pluginCtx = {
476
+ pluginCtx = {
430
477
  tree,
431
478
  options,
432
- events
479
+ events,
480
+ roots,
481
+ map,
482
+ parentCache,
483
+ childrenCache
433
484
  };
434
485
  options?.plugins?.forEach((plugin) => {
435
486
  const api = plugin.setup?.(pluginCtx);
@@ -462,6 +513,21 @@ function useSpliceTree(data, options = {}) {
462
513
  const api = shallowRef();
463
514
  const items = shallowRef(api.value?.items?.() ?? []);
464
515
  const selectedKeys = shallowRef([]);
516
+ const applyExpandedKeys = (value) => {
517
+ if (!api.value || value === void 0) return;
518
+ const list = Array.isArray(value) ? value : [value];
519
+ const toExpand = /* @__PURE__ */ new Set();
520
+ for (const id of list) {
521
+ const node = api.value.getNode(id);
522
+ if (!node) continue;
523
+ let cur = node;
524
+ while (cur) {
525
+ toExpand.add(cur.id);
526
+ cur = cur.getParent();
527
+ }
528
+ }
529
+ if (toExpand.size) api.value.expand(Array.from(toExpand));
530
+ };
465
531
  const createTree = () => {
466
532
  api.value = createSpliceTree(toValue(data), options);
467
533
  api.value.events.on("visibility", () => {
@@ -470,14 +536,22 @@ function useSpliceTree(data, options = {}) {
470
536
  });
471
537
  items.value = api.value.items();
472
538
  if (api.value?.selectedKeys instanceof Set) selectedKeys.value = Array.from(api.value.selectedKeys);
539
+ applyExpandedKeys(options?.expandedKeys ? toValue(options.expandedKeys) : void 0);
473
540
  };
474
541
  createTree();
475
542
  watch(() => toValue(data), () => {
476
543
  api.value.syncData(toValue(data));
544
+ applyExpandedKeys(options?.expandedKeys ? toValue(options.expandedKeys) : void 0);
477
545
  }, {
478
546
  deep: true,
479
547
  immediate: false
480
548
  });
549
+ watch(() => options?.expandedKeys ? toValue(options.expandedKeys) : void 0, (val) => {
550
+ applyExpandedKeys(val);
551
+ }, {
552
+ deep: true,
553
+ immediate: true
554
+ });
481
555
  return {
482
556
  ...api.value,
483
557
  items,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@splicetree/adapter-vue",
3
3
  "type": "module",
4
- "version": "3.0.0",
4
+ "version": "3.0.2",
5
5
  "author": {
6
6
  "email": "michael.cocova@gmail.com",
7
7
  "name": "Michael Cocova"
@@ -30,7 +30,7 @@
30
30
  "unplugin-vue": "^7.1.0",
31
31
  "vue": "^3.0.0",
32
32
  "vue-tsc": "^3.1.5",
33
- "@splicetree/core": "3.0.0"
33
+ "@splicetree/core": "3.0.2"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"