Skip to content

Commit cfc5045

Browse files
author
lishiwen
committed
refactor: shapeflags
1 parent f0914e4 commit cfc5045

File tree

5 files changed

+86
-33
lines changed

5 files changed

+86
-33
lines changed

lib/m-vue.cjs.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,39 @@
22

33
Object.defineProperty(exports, '__esModule', { value: true });
44

5+
function isStructObject(value) {
6+
return Object.prototype.toString.call(value) === "[object Object]";
7+
}
8+
function isArray(value) {
9+
return Object.prototype.toString.call(value) === "[object Array]";
10+
}
11+
function isString(value) {
12+
return Object.prototype.toString.call(value) === "[object String]";
13+
}
14+
515
function createVNode(type, props, children) {
616
const vnode = {
717
type,
818
props,
919
children,
20+
shapeFlag: getShapeFlag(type),
1021
el: null,
1122
};
23+
childrenShapeFlag(vnode);
1224
return vnode;
1325
}
14-
15-
function isStructObject(value) {
16-
return Object.prototype.toString.call(value) === "[object Object]";
17-
}
18-
function isArray(value) {
19-
return Object.prototype.toString.call(value) === "[object Array]";
26+
function getShapeFlag(type) {
27+
return isString(type)
28+
? 1 /* ShapeFlags.ELEMENT */
29+
: 2 /* ShapeFlags.STATEFUL_COMPONENT */;
2030
}
21-
function isString(value) {
22-
return Object.prototype.toString.call(value) === "[object String]";
31+
function childrenShapeFlag(vNode) {
32+
if (isString(vNode.children)) {
33+
vNode.shapeFlag |= 4 /* ShapeFlags.TEXT_CHILDREN */;
34+
}
35+
if (isArray(vNode.children)) {
36+
vNode.shapeFlag |= 8 /* ShapeFlags.ARRAY_CHILDREN */;
37+
}
2338
}
2439

2540
const PublicPropertiesMaps = {
@@ -79,11 +94,10 @@ function render(vnode, container) {
7994
patch(vnode, container);
8095
}
8196
function patch(vnode, container) {
82-
// TODO(branlice): 判断是element 还是component
83-
if (typeof vnode.type === "string") {
97+
if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
8498
processElement(vnode, container);
8599
}
86-
if (isStructObject(vnode.type)) {
100+
if (vnode.shapeFlag & 2 /* ShapeFlags.STATEFUL_COMPONENT */) {
87101
processComponent(vnode, container);
88102
}
89103
}
@@ -103,10 +117,10 @@ function mountElement(vnode, container) {
103117
// vnode.el -> element.el
104118
const el = (vnode.el = document.createElement(vnode.type));
105119
// children
106-
if (isString(vnode.children)) {
120+
if (vnode.shapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
107121
el.textContent = vnode.children;
108122
}
109-
else if (isArray(vnode.children)) {
123+
else if (vnode.shapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
110124
mountChildren(vnode.children, el);
111125
}
112126
// props

lib/m-vue.esm.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1+
function isStructObject(value) {
2+
return Object.prototype.toString.call(value) === "[object Object]";
3+
}
4+
function isArray(value) {
5+
return Object.prototype.toString.call(value) === "[object Array]";
6+
}
7+
function isString(value) {
8+
return Object.prototype.toString.call(value) === "[object String]";
9+
}
10+
111
function createVNode(type, props, children) {
212
const vnode = {
313
type,
414
props,
515
children,
16+
shapeFlag: getShapeFlag(type),
617
el: null,
718
};
19+
childrenShapeFlag(vnode);
820
return vnode;
921
}
10-
11-
function isStructObject(value) {
12-
return Object.prototype.toString.call(value) === "[object Object]";
13-
}
14-
function isArray(value) {
15-
return Object.prototype.toString.call(value) === "[object Array]";
22+
function getShapeFlag(type) {
23+
return isString(type)
24+
? 1 /* ShapeFlags.ELEMENT */
25+
: 2 /* ShapeFlags.STATEFUL_COMPONENT */;
1626
}
17-
function isString(value) {
18-
return Object.prototype.toString.call(value) === "[object String]";
27+
function childrenShapeFlag(vNode) {
28+
if (isString(vNode.children)) {
29+
vNode.shapeFlag |= 4 /* ShapeFlags.TEXT_CHILDREN */;
30+
}
31+
if (isArray(vNode.children)) {
32+
vNode.shapeFlag |= 8 /* ShapeFlags.ARRAY_CHILDREN */;
33+
}
1934
}
2035

2136
const PublicPropertiesMaps = {
@@ -75,11 +90,10 @@ function render(vnode, container) {
7590
patch(vnode, container);
7691
}
7792
function patch(vnode, container) {
78-
// TODO(branlice): 判断是element 还是component
79-
if (typeof vnode.type === "string") {
93+
if (vnode.shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
8094
processElement(vnode, container);
8195
}
82-
if (isStructObject(vnode.type)) {
96+
if (vnode.shapeFlag & 2 /* ShapeFlags.STATEFUL_COMPONENT */) {
8397
processComponent(vnode, container);
8498
}
8599
}
@@ -99,10 +113,10 @@ function mountElement(vnode, container) {
99113
// vnode.el -> element.el
100114
const el = (vnode.el = document.createElement(vnode.type));
101115
// children
102-
if (isString(vnode.children)) {
116+
if (vnode.shapeFlag & 4 /* ShapeFlags.TEXT_CHILDREN */) {
103117
el.textContent = vnode.children;
104118
}
105-
else if (isArray(vnode.children)) {
119+
else if (vnode.shapeFlag & 8 /* ShapeFlags.ARRAY_CHILDREN */) {
106120
mountChildren(vnode.children, el);
107121
}
108122
// props

src/runtime-core/createVNode.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1+
import { ShapeFlags } from "../shared/ShapeFlags";
2+
import { isArray, isString } from "../shared/type";
3+
14
export function createVNode(type, props?, children?) {
25
const vnode = {
36
type,
47
props,
58
children,
9+
shapeFlag: getShapeFlag(type),
610
el: null,
711
};
812

13+
childrenShapeFlag(vnode);
14+
915
return vnode;
16+
}
17+
18+
function getShapeFlag(type) {
19+
return isString(type)
20+
? ShapeFlags.ELEMENT
21+
: ShapeFlags.STATEFUL_COMPONENT;
22+
}
23+
24+
function childrenShapeFlag(vNode) {
25+
if (isString(vNode.children)) {
26+
vNode.shapeFlag |= ShapeFlags.TEXT_CHILDREN;
27+
}
28+
if (isArray(vNode.children)) {
29+
vNode.shapeFlag |= ShapeFlags.ARRAY_CHILDREN;
30+
}
1031
}

src/runtime-core/render.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { isArray, isString, isStructObject } from "../shared/index";
2+
import { ShapeFlags } from "../shared/ShapeFlags";
23
import { createComponentInstance, setupComponent } from "./component";
34

45
export function render(vnode, container) {
56
patch(vnode, container);
67
}
78

89
export function patch(vnode, container) {
9-
// TODO(branlice): 判断是element 还是component
10-
if (typeof vnode.type === "string") {
10+
if (vnode.shapeFlag & ShapeFlags.ELEMENT) {
1111
processElement(vnode, container);
1212
}
13-
if (isStructObject(vnode.type)) {
13+
if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
1414
processComponent(vnode, container);
1515
}
1616
}
@@ -33,14 +33,12 @@ function mountElement(vnode: any, container: any) {
3333
// vnode type -> div/span
3434
// vnode.el -> element.el
3535
const el = (vnode.el = document.createElement(vnode.type));
36-
3736
// children
38-
if (isString(vnode.children)) {
37+
if (vnode.shapeFlag & ShapeFlags.TEXT_CHILDREN) {
3938
el.textContent = vnode.children;
40-
} else if (isArray(vnode.children)) {
39+
} else if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
4140
mountChildren(vnode.children, el);
4241
}
43-
4442
// props
4543
addAttrs(vnode, el);
4644

src/shared/ShapeFlags.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const enum ShapeFlags {
2+
ELEMENT = 1, // 0001
3+
STATEFUL_COMPONENT = 1 << 1, // 0010
4+
TEXT_CHILDREN = 1 << 2, // 0100
5+
ARRAY_CHILDREN = 1 << 3, // 1000
6+
}

0 commit comments

Comments
 (0)