@splicetree/adapter-vue 3.0.1 → 3.1.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/dist/index.js +121 -9
- package/package.json +2 -2
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";
|
|
@@ -394,7 +425,10 @@ function createSpliceTree(data, options = {}) {
|
|
|
394
425
|
parentCache,
|
|
395
426
|
childrenCache,
|
|
396
427
|
expandedKeys,
|
|
397
|
-
notify:
|
|
428
|
+
notify: () => {
|
|
429
|
+
applyNodeExtensions();
|
|
430
|
+
emitVisibility();
|
|
431
|
+
}
|
|
398
432
|
}, parentId, children);
|
|
399
433
|
},
|
|
400
434
|
moveNode(id, newParentId, beforeId) {
|
|
@@ -409,6 +443,31 @@ function createSpliceTree(data, options = {}) {
|
|
|
409
443
|
notify: emitVisibility
|
|
410
444
|
}, id, newParentId, beforeId);
|
|
411
445
|
},
|
|
446
|
+
remove(ids) {
|
|
447
|
+
removeNodes({
|
|
448
|
+
map,
|
|
449
|
+
tree,
|
|
450
|
+
roots,
|
|
451
|
+
keyField,
|
|
452
|
+
parentCache,
|
|
453
|
+
childrenCache,
|
|
454
|
+
expandedKeys,
|
|
455
|
+
notify: emitVisibility
|
|
456
|
+
}, ids);
|
|
457
|
+
},
|
|
458
|
+
updateOriginal(id, patch) {
|
|
459
|
+
const node = map.get(id);
|
|
460
|
+
if (!node) return false;
|
|
461
|
+
if (Object.prototype.hasOwnProperty.call(patch, keyField)) return false;
|
|
462
|
+
if (Object.prototype.hasOwnProperty.call(patch, parentField)) {
|
|
463
|
+
const nextParent = patch[parentField];
|
|
464
|
+
if (nextParent !== node.getParent()?.id) tree.moveNode(id, nextParent);
|
|
465
|
+
delete patch[parentField];
|
|
466
|
+
}
|
|
467
|
+
Object.assign(node.original, patch);
|
|
468
|
+
emitVisibility();
|
|
469
|
+
return true;
|
|
470
|
+
},
|
|
412
471
|
syncData(next) {
|
|
413
472
|
tree.data = next;
|
|
414
473
|
const built = buildTree(next, keyField, parentField, expandedKeys);
|
|
@@ -423,13 +482,21 @@ function createSpliceTree(data, options = {}) {
|
|
|
423
482
|
});
|
|
424
483
|
for (const id of toDelete) expandedKeys.delete(id);
|
|
425
484
|
applyNodeExtensions();
|
|
485
|
+
pluginCtx.roots = roots;
|
|
486
|
+
pluginCtx.map = map;
|
|
487
|
+
pluginCtx.parentCache = parentCache;
|
|
488
|
+
pluginCtx.childrenCache = childrenCache;
|
|
426
489
|
emitVisibility();
|
|
427
490
|
}
|
|
428
491
|
};
|
|
429
|
-
|
|
492
|
+
pluginCtx = {
|
|
430
493
|
tree,
|
|
431
494
|
options,
|
|
432
|
-
events
|
|
495
|
+
events,
|
|
496
|
+
roots,
|
|
497
|
+
map,
|
|
498
|
+
parentCache,
|
|
499
|
+
childrenCache
|
|
433
500
|
};
|
|
434
501
|
options?.plugins?.forEach((plugin) => {
|
|
435
502
|
const api = plugin.setup?.(pluginCtx);
|
|
@@ -444,12 +511,56 @@ function createSpliceTree(data, options = {}) {
|
|
|
444
511
|
else if (expand) tree.expand(node.id);
|
|
445
512
|
else tree.collapse(node.id);
|
|
446
513
|
};
|
|
514
|
+
node.updateOriginal = (patch) => {
|
|
515
|
+
tree.updateOriginal(node.id, patch);
|
|
516
|
+
};
|
|
447
517
|
}
|
|
448
518
|
}
|
|
449
519
|
applyNodeExtensions();
|
|
450
520
|
return tree;
|
|
451
521
|
}
|
|
452
522
|
|
|
523
|
+
//#endregion
|
|
524
|
+
//#region src/utils.ts
|
|
525
|
+
function isStructuralChange(prev, next, keyField, parentField) {
|
|
526
|
+
const prevMap = /* @__PURE__ */ new Map();
|
|
527
|
+
for (const it of prev ?? []) {
|
|
528
|
+
const id = String(Reflect.get(it, keyField));
|
|
529
|
+
prevMap.set(id, it);
|
|
530
|
+
}
|
|
531
|
+
let structural = false;
|
|
532
|
+
const nextMap = /* @__PURE__ */ new Map();
|
|
533
|
+
for (const it of next ?? []) {
|
|
534
|
+
const id = String(Reflect.get(it, keyField));
|
|
535
|
+
nextMap.set(id, it);
|
|
536
|
+
const old = prevMap.get(id);
|
|
537
|
+
if (!old) {
|
|
538
|
+
structural = true;
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
if (Reflect.get(it, parentField) !== Reflect.get(old, parentField)) structural = true;
|
|
542
|
+
}
|
|
543
|
+
for (const id of prevMap.keys()) if (!nextMap.has(id)) {
|
|
544
|
+
structural = true;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
return structural;
|
|
548
|
+
}
|
|
549
|
+
function applyFieldPatches(api, next, keyField, parentField) {
|
|
550
|
+
for (const it of next ?? []) {
|
|
551
|
+
const id = String(Reflect.get(it, keyField));
|
|
552
|
+
const node = api.getNode(id);
|
|
553
|
+
if (!node) continue;
|
|
554
|
+
const patch = {};
|
|
555
|
+
for (const k of Object.keys(it)) {
|
|
556
|
+
if (k === keyField || k === parentField) continue;
|
|
557
|
+
const nv = it[k];
|
|
558
|
+
if (nv !== node.original?.[k]) patch[k] = nv;
|
|
559
|
+
}
|
|
560
|
+
if (Object.keys(patch).length) api.updateOriginal(id, patch);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
453
564
|
//#endregion
|
|
454
565
|
//#region src/index.ts
|
|
455
566
|
/**
|
|
@@ -488,13 +599,14 @@ function useSpliceTree(data, options = {}) {
|
|
|
488
599
|
applyExpandedKeys(options?.expandedKeys ? toValue(options.expandedKeys) : void 0);
|
|
489
600
|
};
|
|
490
601
|
createTree();
|
|
491
|
-
watch(() => toValue(data), () => {
|
|
492
|
-
|
|
602
|
+
watch(() => toValue(data), (next) => {
|
|
603
|
+
const cfg = options?.configuration ?? {};
|
|
604
|
+
const keyField = cfg.keyField ?? "id";
|
|
605
|
+
const parentField = cfg.parentField ?? "parent";
|
|
606
|
+
if (isStructuralChange(api.value?.data ?? [], next, keyField, parentField)) api.value.syncData(next);
|
|
607
|
+
else applyFieldPatches(api.value, next, keyField, parentField);
|
|
493
608
|
applyExpandedKeys(options?.expandedKeys ? toValue(options.expandedKeys) : void 0);
|
|
494
|
-
}, {
|
|
495
|
-
deep: true,
|
|
496
|
-
immediate: false
|
|
497
|
-
});
|
|
609
|
+
}, { immediate: false });
|
|
498
610
|
watch(() => options?.expandedKeys ? toValue(options.expandedKeys) : void 0, (val) => {
|
|
499
611
|
applyExpandedKeys(val);
|
|
500
612
|
}, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@splicetree/adapter-vue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0
|
|
4
|
+
"version": "3.1.0",
|
|
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
|
|
33
|
+
"@splicetree/core": "3.1.0"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|