From 6f718190a482357baf95f62314fa814729e9e696 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B4=A4=E5=BF=83?=
<3277200+sentsim@users.noreply.github.com>
Date: Thu, 23 Oct 2025 23:28:32 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20`lay.extend()`=20?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=20(#2879)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 优化 `lay.extend()` 方法
* fix: 优化 lay.extend 合并对象的类型判断
* fix: 优化判断纯对象的方案
* test: 添加可视化简易单元测试模块
---
examples/base.html | 575 ++++++++++++++++++++++++++++-------------
examples/test/test.css | 51 ++++
examples/test/test.js | 172 ++++++++++++
src/modules/lay.js | 141 ++++++++--
4 files changed, 730 insertions(+), 209 deletions(-)
create mode 100644 examples/test/test.css
create mode 100644 examples/test/test.js
diff --git a/examples/base.html b/examples/base.html
index 7c1904db..c8bdedfc 100644
--- a/examples/base.html
+++ b/examples/base.html
@@ -3,206 +3,419 @@
-
-
- 点击按钮开始测试,测试结果打开浏览器控制台查看
-
-
-
-
-
-
-
-
-
+
+
-
+
+
+
-
+console.log(obj);
+ `,
+ expected: { a: [5], b: { ba: 3, bb: 2 }, c: 3 }
+ });
+
+ it({
+ title: '使用 customizer 实现特定字段跳过合并',
+ code: `
+${objNCode}
+const obj = lay.extend({}, ...objN, (objValue, srcValue, key) => {
+ if (key === 'b') {
+ return objValue;
+ }
+});
+console.log(obj);
+ `,
+ expected: { a: [5, 3], b: { ba: 1 }, c: 3 }
+ });
+
+ it({
+ title: '是否存在对象引用',
+ code: `
+const src = { data: [{a: 1, b: 2}] };
+const obj = lay.extend({}, src);
+
+// 修改 obj 数组类型中的对象成员,查看 src 是否被影响
+obj.data[0].a = '11111';
+console.log(obj.data[0].a === src.data[0].a);
+ `,
+ expected: false
+ });
+ });
+
+ tester.describe('lay.treeToFlat', function(it) {
+ const data = [
+ {
+ "title": "节点 1",
+ "id": "1000",
+ "children": [
+ {
+ "title": "节点 1-1",
+ "id": "1001",
+ },
+ {
+ "title": "节点 1-2",
+ "id": "1002",
+ "children": [
+ {
+ "title": "节点 1-2-1",
+ "id": "1003",
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "title": "节点 2",
+ "id": "2000",
+ }
+ ];
+
+ it({
+ title: '树状数据展平',
+ code: `
+const data = ${JSON.stringify(data, null, 2)};
+
+// 树状数据展平
+const flatData = lay.treeToFlat(data, {
+ keepChildren: true // 是否保留 children 字段
+});
+console.log(JSON.stringify(flatData));
+ `,
+ expected: '子节点被展平到一级数组中(控制台查看)',
+ assert(actual, expected) {
+ try {
+ actual = JSON.parse(actual);
+ console.log(`${this.title} : `, actual);
+ return actual.length === 5;
+ } catch (e) {
+ return false
+ }
+ }
+ });
+
+ it({
+ title: '是否存在对象引用',
+ code: `
+const data = ${JSON.stringify(data, null, 2)};
+
+// 树状数据展平
+const flatData = lay.treeToFlat(data, {
+ keepChildren: true // 是否保留 children 字段
+});
+flatData[0].children[0].title="333333"; // 修改数据
+console.log(flatData[0].children[0].title === data[0].children[0].title);
+ `,
+ expected: false
+ });
+ });
+
+ tester.describe('lay.flatToTree', function(it) {
+ const data = [
+ {
+ "title": "节点 1",
+ "id": "1000",
+ "parentId": null
+ },
+ {
+ "title": "节点 1-1",
+ "id": "1001",
+ "parentId": "1000"
+ },
+ {
+ "title": "节点 1-2",
+ "id": "1002",
+ "parentId": "1000"
+ },
+ {
+ "title": "节点 1-2-1",
+ "id": "1003",
+ "parentId": "1002"
+ },
+ {
+ "title": "节点 2",
+ "id": "2000",
+ "parentId": null
+ }
+ ];
+
+ it({
+ title: '平铺数据转树状',
+ code: `
+const data = ${JSON.stringify(data, null, 2)};
+
+const treeData = lay.flatToTree(data); // 平铺数据转树状
+console.log(JSON.stringify(treeData));
+ `,
+ expected: '根据 parentId 字段进行树状数据生成(控制台查看)',
+ assert(actual, expected) {
+ try {
+ actual = JSON.parse(actual);
+ console.log(`${this.title} : `, actual);
+ return actual.length === 2;
+ } catch (e) {
+ return false
+ }
+ }
+ });
+
+ it({
+ title: '是否存在对象引用',
+ code: `
+const data = ${JSON.stringify(data, null, 2)};
+
+const treeData = lay.flatToTree(data); // 平铺数据转树状
+treeData[0].children[0].title="333333"; // 修改数据
+// 查看原始数据是否被修改
+console.log(treeData[0].children[0].title === data[1].title);
+ `,
+ expected: false
+ });
+ });
+
+ // 统计结果
+ tester.stats();
+
+ // 返回顶部
+ util.fixbar();
+ });
+