0
# Reactive System Flags
1
2
Bitwise optimization flags used by Vue's compiler and runtime for efficient rendering, reactivity tracking, and component classification. These flags enable Vue's optimized diff algorithm and selective updates.
3
4
## Capabilities
5
6
### PatchFlags Enum
7
8
Optimization hints for the virtual DOM diffing algorithm, indicating what parts of a VNode might change.
9
10
```typescript { .api }
11
/**
12
* Patch flags for optimized rendering
13
* Used to mark VNodes with information about what might change
14
* Can be combined using bitwise OR (|) and checked using bitwise AND (&)
15
*/
16
enum PatchFlags {
17
/** Indicates an element with dynamic textContent */
18
TEXT = 1,
19
20
/** Indicates an element with dynamic class binding */
21
CLASS = 1 << 1, // 2
22
23
/** Indicates an element with dynamic style binding */
24
STYLE = 1 << 2, // 4
25
26
/** Indicates an element with dynamic props (non-class/style) */
27
PROPS = 1 << 3, // 8
28
29
/** Indicates an element with props with dynamic keys */
30
FULL_PROPS = 1 << 4, // 16
31
32
/** Indicates an element that requires props hydration */
33
NEED_HYDRATION = 1 << 5, // 32
34
35
/** Indicates a fragment whose children order doesn't change */
36
STABLE_FRAGMENT = 1 << 6, // 64
37
38
/** Indicates a fragment with keyed or partially keyed children */
39
KEYED_FRAGMENT = 1 << 7, // 128
40
41
/** Indicates a fragment with unkeyed children */
42
UNKEYED_FRAGMENT = 1 << 8, // 256
43
44
/** Indicates an element that only needs non-props patching */
45
NEED_PATCH = 1 << 9, // 512
46
47
/** Indicates a component with dynamic slots */
48
DYNAMIC_SLOTS = 1 << 10, // 1024
49
50
/** Indicates a fragment created for root comments (dev only) */
51
DEV_ROOT_FRAGMENT = 1 << 11, // 2048
52
53
/** Indicates a cached static vnode (skip entire subtree) */
54
CACHED = -1,
55
56
/** Bail out of optimized mode (force full diff) */
57
BAIL = -2
58
}
59
60
/**
61
* Development-only mapping of patch flags to readable names
62
*/
63
const PatchFlagNames: Record<PatchFlags, string>;
64
```
65
66
### ShapeFlags Enum
67
68
Classification flags for VNode types, indicating the shape and capabilities of virtual nodes.
69
70
```typescript { .api }
71
/**
72
* Shape flags for VNode classification
73
* Used to quickly identify VNode types and their capabilities
74
*/
75
enum ShapeFlags {
76
/** Regular DOM element */
77
ELEMENT = 1,
78
79
/** Functional component */
80
FUNCTIONAL_COMPONENT = 2,
81
82
/** Stateful component */
83
STATEFUL_COMPONENT = 4,
84
85
/** VNode has text children */
86
TEXT_CHILDREN = 8,
87
88
/** VNode has array children */
89
ARRAY_CHILDREN = 16,
90
91
/** VNode has slot children */
92
SLOTS_CHILDREN = 32,
93
94
/** Teleport component */
95
TELEPORT = 64,
96
97
/** Suspense component */
98
SUSPENSE = 128,
99
100
/** Component should be kept alive */
101
COMPONENT_SHOULD_KEEP_ALIVE = 256,
102
103
/** Component is currently kept alive */
104
COMPONENT_KEPT_ALIVE = 512,
105
106
/** Combined flag for any component type */
107
COMPONENT = 6 // STATEFUL_COMPONENT | FUNCTIONAL_COMPONENT
108
}
109
```
110
111
### SlotFlags Enum
112
113
Flags for slot dependency tracking and optimization in Vue components.
114
115
```typescript { .api }
116
/**
117
* Slot flags for dependency tracking
118
* Used to determine when parent components need to force child updates
119
*/
120
enum SlotFlags {
121
/**
122
* Stable slots that only reference slot props or context state
123
* Can fully capture dependencies, parent won't need to force updates
124
*/
125
STABLE = 1,
126
127
/**
128
* Dynamic slots that reference scope variables or have conditional structure
129
* Parent needs to force child updates due to external dependencies
130
*/
131
DYNAMIC = 2,
132
133
/**
134
* Forwarded slots passed down to child components
135
* Update dependency determined at runtime based on parent's slot type
136
*/
137
FORWARDED = 3
138
}
139
140
/**
141
* Development-only mapping of slot flags to readable names
142
*/
143
const slotFlagsText: Record<SlotFlags, string>;
144
```
145
146
**Usage Examples:**
147
148
```typescript
149
import { PatchFlags, ShapeFlags, SlotFlags } from "@vue/shared";
150
151
// Using PatchFlags for optimization
152
function createOptimizedVNode() {
153
// Combine flags for elements with dynamic text and class
154
const patchFlag = PatchFlags.TEXT | PatchFlags.CLASS;
155
156
// During diff, check what needs updating
157
if (patchFlag & PatchFlags.TEXT) {
158
// Update text content
159
updateTextContent();
160
}
161
162
if (patchFlag & PatchFlags.CLASS) {
163
// Update class binding
164
updateClassBinding();
165
}
166
167
return { patchFlag };
168
}
169
170
// Using ShapeFlags for VNode classification
171
function processVNode(vnode: any) {
172
const shapeFlag = vnode.shapeFlag;
173
174
if (shapeFlag & ShapeFlags.ELEMENT) {
175
// Process DOM element
176
processElement(vnode);
177
} else if (shapeFlag & ShapeFlags.COMPONENT) {
178
// Process component (either stateful or functional)
179
processComponent(vnode);
180
}
181
182
// Check children type
183
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
184
// Process array of children
185
processArrayChildren(vnode.children);
186
} else if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
187
// Process text content
188
processTextChildren(vnode.children);
189
}
190
}
191
192
// Using SlotFlags for slot optimization
193
function createSlot(dependencies: any[]) {
194
let slotFlag = SlotFlags.STABLE;
195
196
if (hasScopeVariables(dependencies)) {
197
slotFlag = SlotFlags.DYNAMIC;
198
}
199
200
return { slotFlag };
201
}
202
203
// Checking for special patch flags
204
function handleSpecialCases(patchFlag: number) {
205
if (patchFlag === PatchFlags.CACHED) {
206
// Skip entire subtree - it's cached static content
207
return;
208
}
209
210
if (patchFlag === PatchFlags.BAIL) {
211
// Exit optimized mode and do full diff
212
performFullDiff();
213
}
214
}
215
216
// Development debugging
217
if (__DEV__) {
218
console.log("Patch flag:", PatchFlagNames[PatchFlags.TEXT]); // "TEXT"
219
console.log("Slot flag:", slotFlagsText[SlotFlags.DYNAMIC]); // "DYNAMIC"
220
}
221
```
222
223
### Performance Characteristics
224
225
These flags enable Vue's highly optimized rendering:
226
227
- **Bitwise Operations**: Extremely fast flag checking and combining using `&` and `|`
228
- **Selective Updates**: Only update VNode parts marked by patch flags
229
- **Static Hoisting**: `CACHED` flag allows skipping entire static subtrees
230
- **Component Classification**: Shape flags enable type-specific optimizations
231
- **Slot Optimization**: Slot flags minimize unnecessary component re-renders
232
233
### Flag Combination Patterns
234
235
```typescript
236
// Common flag combinations
237
const dynamicElement = PatchFlags.TEXT | PatchFlags.CLASS | PatchFlags.STYLE;
238
const dynamicComponent = PatchFlags.PROPS | PatchFlags.DYNAMIC_SLOTS;
239
const stableFragment = PatchFlags.STABLE_FRAGMENT;
240
241
// Component with mixed children
242
const mixedComponent = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.ARRAY_CHILDREN;
243
244
// Check for any component type
245
const isComponent = (shapeFlag: number) => shapeFlag & ShapeFlags.COMPONENT;
246
```