Skip to content

Commit a272f2b

Browse files
committed
feat: element diff
1 parent 7337732 commit a272f2b

File tree

6 files changed

+467
-122
lines changed

6 files changed

+467
-122
lines changed

example/patchChildren/PatchChildren.js

Lines changed: 165 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,121 +2,210 @@ import { h } from "../../lib/mini-vue.esm.js";
22
import { ref } from "../../lib/mini-vue.esm.js";
33

44
const isChange = ref(false);
5-
// 默认是顺序不变,新旧节点的数量不变,属性不变
6-
// 第一种情况:(从前往后依次对比)
7-
// 属性变了
8-
// const prevChildren = [h("div", { key: "a", id: "old-a" }, "a")];
9-
// const nextChildren = [h("div", { key: "a", id: "new-a" }, "a")];
10-
11-
//第二种情况:
12-
// 新节点的数量增加了一个
13-
// const prevChildren = [h("div", { key: "a", id: "old-a" }, "a")];
5+
6+
// 1. 左侧的对比
7+
// (a b) c
8+
// (a b) d e
9+
// const prevChildren = [
10+
// h("p", { key: "A" }, "A"),
11+
// h("p", { key: "B" }, "B"),
12+
// h("p", { key: "C" }, "C"),
13+
// ];
1414
// const nextChildren = [
15-
// h("div", { key: "a", id: "new-a" }, "a"),
16-
// h("div", { key: "b" }, "b"),
15+
// h("p", { key: "A" }, "A"),
16+
// h("p", { key: "B" }, "B"),
17+
// h("p", { key: "D" }, "D"),
18+
// h("p", { key: "E" }, "E"),
1719
// ];
1820

19-
// 新节点数量增加两个
20-
// const prevChildren = [h("div", { key: "a", id: "old-a" }, "a")];
21+
// 2. 右侧的对比
22+
// a (b c)
23+
// d e (b c)
24+
// const prevChildren = [
25+
// h("p", { key: "A" }, "A"),
26+
// h("p", { key: "B" }, "B"),
27+
// h("p", { key: "C" }, "C"),
28+
// ];
2129
// const nextChildren = [
22-
// h("div", { key: "a", id: "new-a" }, "a"),
23-
// h("div", { key: "b" }, "b"),
24-
// h("div", { key: "c" }, "c"),
30+
// h("p", { key: "D" }, "D"),
31+
// h("p", { key: "E" }, "E"),
32+
// h("p", { key: "B" }, "B"),
33+
// h("p", { key: "C" }, "C"),
2534
// ];
2635

27-
// 第三种情况:
28-
// 新节点的数量减少了一个
29-
// const prevChildren = [
30-
// h("div", { key: "a" }, "a"),
31-
// h("div", { key: "b" }, "b"),
32-
// h("div", { key: "c" }, "c"),
36+
// 3. 新的比老的长
37+
// 创建新的
38+
// 左侧
39+
// (a b)
40+
// (a b) c
41+
// i = 2, e1 = 1, e2 = 2
42+
// const prevChildren = [h("p", { key: "A" }, "A"), h("p", { key: "B" }, "B")];
43+
// const nextChildren = [
44+
// h("p", { key: "A" }, "A"),
45+
// h("p", { key: "B" }, "B"),
46+
// h("p", { key: "C" }, "C"),
3347
// ];
3448

35-
// const nextChildren = [h("div", { key: "a" }, "a"), h("div", { key: "b" }, "b")];
49+
// 右侧
50+
// (a b)
51+
// c (a b)
52+
// i = 0, e1 = -1, e2 = 0
53+
// const prevChildren = [h("p", { key: "A" }, "A"), h("p", { key: "B" }, "B")];
54+
// const nextChildren = [
55+
// h("p", { key: "C" }, "C"),
56+
// h("p", { key: "A" }, "A"),
57+
// h("p", { key: "B" }, "B"),
58+
// ];
3659

37-
// 新节点的数量减少了两个
60+
// 4. 老的比新的长
61+
// 删除老的
62+
// 左侧
63+
// (a b) c
64+
// (a b)
65+
// i = 2, e1 = 2, e2 = 1
3866
// const prevChildren = [
39-
// h("div", { key: "a" }, "a"),
40-
// h("div", { key: "b" }, "b"),
41-
// h("div", { key: "c" }, "c"),
67+
// h("p", { key: "A" }, "A"),
68+
// h("p", { key: "B" }, "B"),
69+
// h("p", { key: "C" }, "C"),
4270
// ];
71+
// const nextChildren = [h("p", { key: "A" }, "A"), h("p", { key: "B" }, "B")];
4372

44-
// const nextChildren = [h("div", { key: "a" }, "a")];
73+
// 右侧
74+
// a (b c)
75+
// (b c)
76+
// i = 0, e1 = 0, e2 = -1
4577

46-
// 第四种情况:(从后往前依次对比)
47-
// a (b)
48-
// (b)
4978
// const prevChildren = [
50-
// h("div", { key: "a" }, "a"),
51-
// h("div", { key: "b", id: "old-id" }, "b"),
79+
// h("p", { key: "A" }, "A"),
80+
// h("p", { key: "B" }, "B"),
81+
// h("p", { key: "C" }, "C"),
5282
// ];
53-
// const nextChildren = [h("div", { key: "b", id: "new-id" }, "b")];
83+
// const nextChildren = [h("p", { key: "B" }, "B"), h("p", { key: "C" }, "C")];
84+
85+
// 5. 对比中间的部分
86+
// 删除老的 (在老的里面存在,新的里面不存在)
87+
// 5.1
88+
// a,b,(c,d),f,g
89+
// a,b,(e,c),f,g
90+
// D 节点在新的里面是没有的 - 需要删除掉
91+
// C 节点 props 也发生了变化
5492

55-
// 第五种情况
56-
// 顺序变了,但是新老节点都存在
57-
// 先只验证节点的 props 是否正常更新
58-
// todo: 还需要移动位置
59-
// a,b
60-
// b,a
6193
// const prevChildren = [
62-
// h("div", { key: "a", id: "old-a" }, "a"),
63-
// h("div", { key: "b", id: "old-b" }, "b"),
94+
// h("p", { key: "A" }, "A"),
95+
// h("p", { key: "B" }, "B"),
96+
// h("p", { key: "C", id: "c-prev" }, "C"),
97+
// h("p", { key: "D" }, "D"),
98+
// h("p", { key: "F" }, "F"),
99+
// h("p", { key: "G" }, "G"),
64100
// ];
101+
65102
// const nextChildren = [
66-
// h("div", { key: "b", id: "new-b" }, "b"),
67-
// h("div", { key: "a", id: "new-a" }, "a"),
103+
// h("p", { key: "A" }, "A"),
104+
// h("p", { key: "B" }, "B"),
105+
// h("p", { key: "E" }, "E"),
106+
// h("p", { key: "C", id:"c-next" }, "C"),
107+
// h("p", { key: "F" }, "F"),
108+
// h("p", { key: "G" }, "G"),
68109
// ];
69110

70-
// 第六种情况
71-
// 顺序变了,老节点在 newChildren 里面不存在
72-
// 还需要处理一下位置的移动
73-
// a,b,c
74-
// b,a
111+
// 5.1.1
112+
// a,b,(c,e,d),f,g
113+
// a,b,(e,c),f,g
114+
// 中间部分,老的比新的多, 那么多出来的直接就可以被干掉(优化删除逻辑)
75115
// const prevChildren = [
76-
// h("div", { key: "a", id: "old-a" }, "a"),
77-
// h("div", { key: "b", id: "old-b" }, "b"),
78-
// h("div", { key: "c", id: "old-c" }, "c"),
116+
// h("p", { key: "A" }, "A"),
117+
// h("p", { key: "B" }, "B"),
118+
// h("p", { key: "C", id: "c-prev" }, "C"),
119+
// h("p", { key: "E" }, "E"),
120+
// h("p", { key: "D" }, "D"),
121+
// h("p", { key: "F" }, "F"),
122+
// h("p", { key: "G" }, "G"),
79123
// ];
124+
80125
// const nextChildren = [
81-
// h("div", { key: "b", id: "new-b" }, "b"),
82-
// h("div", { key: "a", id: "new-a" }, "a"),
126+
// h("p", { key: "A" }, "A"),
127+
// h("p", { key: "B" }, "B"),
128+
// h("p", { key: "E" }, "E"),
129+
// h("p", { key: "C", id:"c-next" }, "C"),
130+
// h("p", { key: "F" }, "F"),
131+
// h("p", { key: "G" }, "G"),
83132
// ];
84133

85-
// 第七种情况
86-
// 顺序变了,新节点在 oldChildren 里面不存在
87-
// 需要创建新节点
88-
// 还需要移动元素位置( anchor 有值的情况下 )
134+
// 2 移动 (节点存在于新的和老的里面,但是位置变了)
135+
136+
// 2.1
137+
// a,b,(c,d,e),f,g
138+
// a,b,(e,c,d),f,g
139+
// 最长子序列: [1,2]
140+
89141
// const prevChildren = [
90-
// h("div", { key: "a", id: "old-a" }, "a"),
91-
// h("div", { key: "b", id: "old-b" }, "b"),
142+
// h("p", { key: "A" }, "A"),
143+
// h("p", { key: "B" }, "B"),
144+
// h("p", { key: "C" }, "C"),
145+
// h("p", { key: "D" }, "D"),
146+
// h("p", { key: "E" }, "E"),
147+
// h("p", { key: "F" }, "F"),
148+
// h("p", { key: "G" }, "G"),
92149
// ];
150+
93151
// const nextChildren = [
94-
// h("div", { key: "b", id: "new-b" }, "b"),
95-
// h("div", { key: "a", id: "new-a" }, "a"),
96-
// h("div", { key: "c", id: "new-c" }, "c"),
152+
// h("p", { key: "A" }, "A"),
153+
// h("p", { key: "B" }, "B"),
154+
// h("p", { key: "E" }, "E"),
155+
// h("p", { key: "C" }, "C"),
156+
// h("p", { key: "D" }, "D"),
157+
// h("p", { key: "F" }, "F"),
158+
// h("p", { key: "G" }, "G"),
97159
// ];
98160

99-
// 第八种情况
100-
// 移动元素位置( anchor 没有值的情况下 )
101-
// 要移动的元素是属于最后一个位置
161+
// 2.2
162+
// a,b,(c,d,e,z),f,g
163+
// a,b,(d,c,y,e),f,g
164+
// 最长子序列: [1,3]
165+
102166
// const prevChildren = [
103-
// h("div", { key: "a", id: "old-a" }, "a"),
104-
// h("div", { key: "b", id: "old-b" }, "b"),
167+
// h("p", { key: "A" }, "A"),
168+
// h("p", { key: "B" }, "B"),
169+
// h("p", { key: "C" }, "C"),
170+
// h("p", { key: "D" }, "D"),
171+
// h("p", { key: "E" }, "E"),
172+
// h("p", { key: "Z" }, "Z"),
173+
// h("p", { key: "F" }, "F"),
174+
// h("p", { key: "G" }, "G"),
105175
// ];
176+
106177
// const nextChildren = [
107-
// h("div", { key: "b", id: "old-b" }, "b"),
108-
// h("div", { key: "a", id: "old-a" }, "a"),
178+
// h("p", { key: "A" }, "A"),
179+
// h("p", { key: "B" }, "B"),
180+
// h("p", { key: "D" }, "D"),
181+
// h("p", { key: "C" }, "C"),
182+
// h("p", { key: "Y" }, "Y"),
183+
// h("p", { key: "E" }, "E"),
184+
// h("p", { key: "F" }, "F"),
185+
// h("p", { key: "G" }, "G"),
109186
// ];
110187

111-
// 在左侧添加新元素
112-
// (a b)
113-
// c (a b)
114-
// i = 0, e1 = -1, e2 = 0
115-
const prevChildren = [h("p", { key: "A" }, "A"), h("p", { key: "B" }, "B")];
116-
const nextChildren = [
188+
// 3. 创建新的节点
189+
// a,b,(c,e),f,g
190+
// a,b,(e,c,d),f,g
191+
// d 节点在老的节点中不存在,新的里面存在,所以需要创建
192+
const prevChildren = [
193+
h("p", { key: "A" }, "A"),
194+
h("p", { key: "B" }, "B"),
117195
h("p", { key: "C" }, "C"),
196+
h("p", { key: "E" }, "E"),
197+
h("p", { key: "F" }, "F"),
198+
h("p", { key: "G" }, "G"),
199+
];
200+
201+
const nextChildren = [
118202
h("p", { key: "A" }, "A"),
119203
h("p", { key: "B" }, "B"),
204+
h("p", { key: "E" }, "E"),
205+
h("p", { key: "C" }, "C"),
206+
h("p", { key: "D" }, "D"),
207+
h("p", { key: "F" }, "F"),
208+
h("p", { key: "G" }, "G"),
120209
];
121210

122211
export default {

0 commit comments

Comments
 (0)