Internal utility functions shared across Vue.js packages for DOM manipulation, type checking, and general utilities
—
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.
Optimization hints for the virtual DOM diffing algorithm, indicating what parts of a VNode might change.
/**
* Patch flags for optimized rendering
* Used to mark VNodes with information about what might change
* Can be combined using bitwise OR (|) and checked using bitwise AND (&)
*/
enum PatchFlags {
/** Indicates an element with dynamic textContent */
TEXT = 1,
/** Indicates an element with dynamic class binding */
CLASS = 1 << 1, // 2
/** Indicates an element with dynamic style binding */
STYLE = 1 << 2, // 4
/** Indicates an element with dynamic props (non-class/style) */
PROPS = 1 << 3, // 8
/** Indicates an element with props with dynamic keys */
FULL_PROPS = 1 << 4, // 16
/** Indicates an element that requires props hydration */
NEED_HYDRATION = 1 << 5, // 32
/** Indicates a fragment whose children order doesn't change */
STABLE_FRAGMENT = 1 << 6, // 64
/** Indicates a fragment with keyed or partially keyed children */
KEYED_FRAGMENT = 1 << 7, // 128
/** Indicates a fragment with unkeyed children */
UNKEYED_FRAGMENT = 1 << 8, // 256
/** Indicates an element that only needs non-props patching */
NEED_PATCH = 1 << 9, // 512
/** Indicates a component with dynamic slots */
DYNAMIC_SLOTS = 1 << 10, // 1024
/** Indicates a fragment created for root comments (dev only) */
DEV_ROOT_FRAGMENT = 1 << 11, // 2048
/** Indicates a cached static vnode (skip entire subtree) */
CACHED = -1,
/** Bail out of optimized mode (force full diff) */
BAIL = -2
}
/**
* Development-only mapping of patch flags to readable names
*/
const PatchFlagNames: Record<PatchFlags, string>;Classification flags for VNode types, indicating the shape and capabilities of virtual nodes.
/**
* Shape flags for VNode classification
* Used to quickly identify VNode types and their capabilities
*/
enum ShapeFlags {
/** Regular DOM element */
ELEMENT = 1,
/** Functional component */
FUNCTIONAL_COMPONENT = 2,
/** Stateful component */
STATEFUL_COMPONENT = 4,
/** VNode has text children */
TEXT_CHILDREN = 8,
/** VNode has array children */
ARRAY_CHILDREN = 16,
/** VNode has slot children */
SLOTS_CHILDREN = 32,
/** Teleport component */
TELEPORT = 64,
/** Suspense component */
SUSPENSE = 128,
/** Component should be kept alive */
COMPONENT_SHOULD_KEEP_ALIVE = 256,
/** Component is currently kept alive */
COMPONENT_KEPT_ALIVE = 512,
/** Combined flag for any component type */
COMPONENT = 6 // STATEFUL_COMPONENT | FUNCTIONAL_COMPONENT
}Flags for slot dependency tracking and optimization in Vue components.
/**
* Slot flags for dependency tracking
* Used to determine when parent components need to force child updates
*/
enum SlotFlags {
/**
* Stable slots that only reference slot props or context state
* Can fully capture dependencies, parent won't need to force updates
*/
STABLE = 1,
/**
* Dynamic slots that reference scope variables or have conditional structure
* Parent needs to force child updates due to external dependencies
*/
DYNAMIC = 2,
/**
* Forwarded slots passed down to child components
* Update dependency determined at runtime based on parent's slot type
*/
FORWARDED = 3
}
/**
* Development-only mapping of slot flags to readable names
*/
const slotFlagsText: Record<SlotFlags, string>;Usage Examples:
import { PatchFlags, ShapeFlags, SlotFlags } from "@vue/shared";
// Using PatchFlags for optimization
function createOptimizedVNode() {
// Combine flags for elements with dynamic text and class
const patchFlag = PatchFlags.TEXT | PatchFlags.CLASS;
// During diff, check what needs updating
if (patchFlag & PatchFlags.TEXT) {
// Update text content
updateTextContent();
}
if (patchFlag & PatchFlags.CLASS) {
// Update class binding
updateClassBinding();
}
return { patchFlag };
}
// Using ShapeFlags for VNode classification
function processVNode(vnode: any) {
const shapeFlag = vnode.shapeFlag;
if (shapeFlag & ShapeFlags.ELEMENT) {
// Process DOM element
processElement(vnode);
} else if (shapeFlag & ShapeFlags.COMPONENT) {
// Process component (either stateful or functional)
processComponent(vnode);
}
// Check children type
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
// Process array of children
processArrayChildren(vnode.children);
} else if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
// Process text content
processTextChildren(vnode.children);
}
}
// Using SlotFlags for slot optimization
function createSlot(dependencies: any[]) {
let slotFlag = SlotFlags.STABLE;
if (hasScopeVariables(dependencies)) {
slotFlag = SlotFlags.DYNAMIC;
}
return { slotFlag };
}
// Checking for special patch flags
function handleSpecialCases(patchFlag: number) {
if (patchFlag === PatchFlags.CACHED) {
// Skip entire subtree - it's cached static content
return;
}
if (patchFlag === PatchFlags.BAIL) {
// Exit optimized mode and do full diff
performFullDiff();
}
}
// Development debugging
if (__DEV__) {
console.log("Patch flag:", PatchFlagNames[PatchFlags.TEXT]); // "TEXT"
console.log("Slot flag:", slotFlagsText[SlotFlags.DYNAMIC]); // "DYNAMIC"
}These flags enable Vue's highly optimized rendering:
& and |CACHED flag allows skipping entire static subtrees// Common flag combinations
const dynamicElement = PatchFlags.TEXT | PatchFlags.CLASS | PatchFlags.STYLE;
const dynamicComponent = PatchFlags.PROPS | PatchFlags.DYNAMIC_SLOTS;
const stableFragment = PatchFlags.STABLE_FRAGMENT;
// Component with mixed children
const mixedComponent = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.ARRAY_CHILDREN;
// Check for any component type
const isComponent = (shapeFlag: number) => shapeFlag & ShapeFlags.COMPONENT;Install with Tessl CLI
npx tessl i tessl/npm-vue--shared