11//h函数,用于返回一个VNode对象
22const h = ( tag , props , children ) => {
3- //vnode -> javascript对象 -> {}
4- return {
5- tag,
6- props,
7- children
8- }
3+ //vnode -> javascript对象 -> {}
4+ return {
5+ tag,
6+ props,
7+ children
8+ }
99}
1010
1111//mount函数,用于将VNode对象挂载到DOM上
1212const mount = ( vnode , container ) => {
13- //vnode -> element
14- //1.创建出真实的元素,并且在vnode上保留el
15- const el = vnode . el = document . createElement ( vnode . tag )
16- //2.处理props
17- if ( vnode . props ) {
18- for ( const key in vnode . props ) {
19- const value = vnode . props [ key ]
20- if ( key . startsWith ( "on" ) ) {
21- el . addEventListener ( key . slice ( 2 ) . toLowerCase ( ) , value )
22- } else {
23- el . setAttribute ( key , value )
24- }
13+ //vnode -> element
14+ //1.创建出真实的元素,并且在vnode上保留el
15+ const el = vnode . el = document . createElement ( vnode . tag )
16+ //2.处理props
17+ if ( vnode . props ) {
18+ for ( const key in vnode . props ) {
19+ const value = vnode . props [ key ]
20+ if ( key . startsWith ( "on" ) ) {
21+ el . addEventListener ( key . slice ( 2 ) . toLowerCase ( ) , value )
22+ } else {
23+ el . setAttribute ( key , value )
24+ }
25+ }
2526 }
26- }
27- //3.处理children
28- if ( vnode . children ) {
29- if ( typeof vnode . children === "string" ) {
30- el . textContent = vnode . children
31- } else {
32- vnode . children . forEach ( item => {
33- mount ( item , el )
34- } )
27+ //3.处理children
28+ if ( vnode . children ) {
29+ if ( typeof vnode . children === "string" ) {
30+ el . textContent = vnode . children
31+ } else {
32+ vnode . children . forEach ( item => {
33+ mount ( item , el )
34+ } )
35+ }
3536 }
36- }
3737
38- //4.将el挂载到container
39- container . appendChild ( el )
38+ //4.将el挂载到container
39+ container . appendChild ( el )
4040}
4141
4242//pathch函数,用于对两个VNode进行对比,决定如何处理新的VNode
4343const patch = ( node1 , node2 ) => {
44- //标签不相等时,直接将vnode1删除
45- if ( node1 . tag !== node2 . tag ) {
46- //获取父元素
47- const n1Parent = node1 . el . parentElement
48- //删除node1
49- n1Parent . removeChild ( n1Parent . el )
50- //将node2挂载到父元素上
51- mount ( node2 , n1Parent )
52- } else { //tag相等时,props不相等时
53- //1.取出element对象,并在node2中进行保存
54- const el = node2 . el = node1 . el
55-
56- }
57- // const patch = (n1, n2) => {
58- // else {
59- // //1.取出element对象,并且在n2中进行保存
60- // const el = (n2.el = n1Element.el);
61-
62- // //2.处理props
63- // const oldProps = n1.props || {};
64- // const newProps = n2.props || {};
65- // //2.1.获取所有的newProps添加到el
66- // for (const key in newProps) {
67- // const oldValue = oldProps[key];
68- // const newValue = newProps[key];
69- // if (newValue !== oldValue) {
70- // if (key.startsWith("on")) {
71- // el.addEventListener(key.slice(2).toLowerCase, newValue);
72- // } else {
73- // el.setAttribute(key, newValue);
74- // }
75- // }
76- // }
77-
78- // //2.2. 删除旧的props
79- // for (const key in oldProps) {
80- // if (key.startsWith("on")) {
81- // const value = oldProps[key];
82- // el.removeEventListener(key.slice(2).toLowerCase, value);
83- // }
84- // if (!(key in newProps)) {
85- // el.removeAttribute(key);
86- // }
87- // }
88-
89- // //3.处理children
90- // const oldChildren = n1.children || [];
91- // const newChildren = n2.children || [];
92- // if (typeof newChildren === "string") {
93- // //情况一:newChildrenben本身是一个string
94- // //edge case
95- // if (typeof oldChildren === "string") {
96- // if (newChildren !== oldChildren) {
97- // el.textContent = newChildren;
98- // }
99- // } else {
100- // el.innerHTML = newChildren;
101- // }
102- // } else {
103- // //情况二: newChildren本身是一个数组
104- // if (typeof oldChildren === "string") {
105- // el.innerHTML = "";
106- // newChildren.forEach((item) => {
107- // mount(item, el);
108- // });
109- // } else {
110- // //oldChildren: [v1, v2, v3, v7, v9]
111- // //newChildren: [v1, v5, v6]
112- // //1.前面有相同节点的原生进行patch操作
113- // const commonLength = Math.min(oldChildren.length, newChildren.length);
114- // for (let i = 0; i < commonLength; i++) {
115- // patch(oldChildren[i], newChildren[i]);
116- // }
44+ //标签不相等时,直接将vnode1删除
45+ if ( node1 . tag !== node2 . tag ) {
46+ //获取父元素
47+ const n1Parent = node1 . el . parentElement
48+ //删除node1
49+ n1Parent . removeChild ( n1Parent . el )
50+ //将node2挂载到父元素上
51+ mount ( node2 , n1Parent )
52+ } else { //tag相等时,props不相等时
53+ //1.取出element对象,并在node2中进行保存
54+ const el = node1 . el = node2 . el
55+ //2.处理props
56+ const oldProps = node1 . props || { }
57+ const newProps = node2 . props || { }
58+ //2.1获取所有的newProps添加到el
59+ for ( const key in newProps ) {
60+ const oldValue = oldProps [ key ]
61+ const newValue = newProps [ key ]
62+ if ( newValue !== oldValue ) {
63+ if ( key . startsWith ( "on" ) ) {
64+ el . addEventListener ( key . slice ( 2 ) . toLowerCase , value )
65+ } else {
66+ el . setAttribute ( key , value )
67+ }
68+ }
69+ }
70+ //2.2删除旧的props
71+ for ( const key in oldProps ) {
72+ if ( key . startsWith ( "on" ) ) {
73+ const value = oldProps [ key ]
74+ el . removeEventListener ( key . slice ( 2 ) . toLowerCase , value )
75+ }
76+ if ( ! ( key in newProps ) ) {
77+ el . removeAttribute ( key )
78+ }
79+ }
80+ }
81+ // const patch = (n1, n2) => {
82+ // //3.处理children
83+ // const oldChildren = n1.children || [];
84+ // const newChildren = n2.children || [];
85+ // if (typeof newChildren === "string") {
86+ // //情况一:newChildrenben本身是一个string
87+ // //edge case
88+ // if (typeof oldChildren === "string") {
89+ // if (newChildren !== oldChildren) {
90+ // el.textContent = newChildren;
91+ // }
92+ // } else {
93+ // el.innerHTML = newChildren;
94+ // }
95+ // } else {
96+ // //情况二: newChildren本身是一个数组
97+ // if (typeof oldChildren === "string") {
98+ // el.innerHTML = "";
99+ // newChildren.forEach((item) => {
100+ // mount(item, el);
101+ // });
102+ // } else {
103+ // //oldChildren: [v1, v2, v3, v7, v9]
104+ // //newChildren: [v1, v5, v6]
105+ // //1.前面有相同节点的原生进行patch操作
106+ // const commonLength = Math.min(oldChildren.length, newChildren.length);
107+ // for (let i = 0; i < commonLength; i++) {
108+ // patch(oldChildren[i], newChildren[i]);
109+ // }
117110
118- // //2.newChildren.length > oldChildren.length
119- // if (newChildren.length > oldChildren.length) {
120- // newChildren.slice(oldChildren.length).forEach((item) => {
121- // mount(item, el);
122- // });
123- // }
111+ // //2.newChildren.length > oldChildren.length
112+ // if (newChildren.length > oldChildren.length) {
113+ // newChildren.slice(oldChildren.length).forEach((item) => {
114+ // mount(item, el);
115+ // });
116+ // }
124117
125- // //3.newChildren.length < oldChildren.length
126- // if (newChildren.length < oldChildren.length) {
127- // oldChildren.slice(newChildren.length).forEach((item) => {
128- // el.removeChild(item.el);
129- // });
130- // }
131- // }
132- // }
133- // }
134- // };
118+ // //3.newChildren.length < oldChildren.length
119+ // if (newChildren.length < oldChildren.length) {
120+ // oldChildren.slice(newChildren.length).forEach((item) => {
121+ // el.removeChild(item.el);
122+ // });
123+ // }
124+ // }
125+ // }
126+ // }
127+ // };
0 commit comments