阿里云主机折上折
  • 微信号
Current Site:Index > Overview of Vue 3's Overall Architecture

Overview of Vue 3's Overall Architecture

Author:Chuan Chen 阅读数:25059人阅读 分类: Vue.js

Overview of Vue3's Architecture

Vue3's architectural design revolves around the reactivity system, compiler, and runtime core. Compared to Vue2, Vue3 has made significant improvements in performance optimization and code organization, adopting a Monorepo management approach that splits core functionalities into independent modules.

Reactivity System Refactoring

Vue3 uses Proxy instead of Object.defineProperty to implement reactivity, addressing the limitations in Vue2 regarding array mutation methods and object property additions. The new reactivity system consists of two main parts:

// Basic reactivity example
import { reactive, effect } from 'vue'

const state = reactive({
  count: 0
})

effect(() => {
  console.log('count changed:', state.count)
})

state.count++ // Triggers effect execution

The core reactivity module @vue/reactivity is entirely standalone and can be used independently. Its internal implementation includes:

  1. Dependency tracking system: Establishes property-effect mappings via the track function.
  2. Update triggering system: Notifies related effects to re-execute via the trigger function.
  3. Nested effect handling: Manages nested scenarios using an effect stack.

Compiler Optimizations

Vue3's compiler transforms templates into more efficient render function code, with key optimizations including:

  1. Static node hoisting: Extracts static nodes outside the render function.
  2. Patch flags: Adds markers to dynamic nodes to reduce diff comparisons.
  3. Block tree optimization: Divides templates into nested "blocks" to minimize dynamic binding traversal.
// Template before compilation
<div>
  <span>Static content</span>
  <span>{{ dynamic }}</span>
</div>

// Compiled output
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"

export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("span", null, "Static content"),
    _createVNode("span", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
  ]))
}

Runtime Core

The runtime core includes the virtual DOM and component system, with major improvements such as:

  1. Faster virtual DOM diff algorithm.
  2. Support for new features like Fragment and Teleport.
  3. Component instance proxy mechanism.

Example component instance structure:

const instance = {
  uid: 0,
  type: Component,
  parent: null,
  appContext: null,
  root: null,
  next: null,
  subTree: null,
  update: null,
  render: null,
  proxy: null,
  exposed: null,
  withProxy: null,
  effects: null,
  provides: parent ? parent.provides : Object.create(appContext.provides),
  accessCache: null,
  renderCache: [],
  
  // State-related
  ctx: {},
  data: {},
  props: {},
  attrs: {},
  slots: {},
  refs: {},
  
  // Lifecycle
  isMounted: false,
  isUnmounted: false,
  bm: null,  // beforeMount hooks
  m: null,   // mounted hooks
  bu: null,  // beforeUpdate hooks
  u: null,   // updated hooks
  um: null,  // unmounted hooks
  bum: null, // beforeUnmount hooks
  da: null,  // deactivated hooks
  a: null    // activated hooks
}

Composition API Design

The Composition API is one of Vue3's most important architectural improvements, addressing code organization issues in complex components with the Options API. Core APIs include:

import { ref, computed, watch, provide, inject } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    
    watch(count, (newVal) => {
      console.log('count changed', newVal)
    })
    
    provide('count', count)
    
    return {
      count,
      double
    }
  }
}

The setup function executes between beforeCreate and created, when the component instance is not fully created but the reactivity system is ready.

Modular Architecture

Vue3 adopts a Monorepo structure, with key packages including:

  1. vue: Full version.
  2. @vue/runtime-core: Runtime core.
  3. @vue/runtime-dom: Browser platform runtime.
  4. @vue/compiler-sfc: Single-file component compiler.
  5. @vue/reactivity: Reactivity system.
  6. @vue/shared: Shared utility functions.

This architecture allows Vue3 to be used on-demand and facilitates custom renderer development. For example, creating a custom renderer:

import { createRenderer } from '@vue/runtime-core'

const { render, createApp } = createRenderer({
  patchProp,
  insert,
  remove,
  createElement
  // ...Other platform-specific APIs
})

export { render, createApp }

Performance Optimization Strategies

Vue3 implements performance optimizations at multiple levels:

  1. Compile-time optimizations: Reduce runtime overhead through static analysis.
  2. Virtual DOM optimizations: Improve diff algorithm time complexity from O(n^3) to O(n).
  3. Memory optimizations: Use more compact data structures.
  4. Tree-shaking optimizations: Better ES module design for dead code elimination.

Key virtual DOM diff improvements:

// Traditional diff algorithm
function diff(oldVNode, newVNode) {
  // Full comparison
}

// Vue3 optimized diff
function patchKeyedChildren(c1, c2) {
  // 1. Front-to-back comparison
  // 2. Back-to-front comparison
  // 3. Common sequence handling
  // 4. Unknown sequence handling
}

Type System Support

Vue3 is rewritten in TypeScript, providing comprehensive type definitions. Key types include:

interface ComponentInternalInstance {
  uid: number
  type: ConcreteComponent
  parent: ComponentInternalInstance | null
  root: ComponentInternalInstance
  appContext: AppContext
  // ...
}

interface VNode {
  __v_isVNode: true
  type: VNodeTypes
  props: VNodeProps | null
  key: string | number | null
  // ...
}

type CompilerOptions = {
  isNativeTag?: (tag: string) => boolean
  isCustomElement?: (tag: string) => boolean
  // ...
}

Custom Renderer API

Vue3 supports non-DOM environments through the custom renderer API, with core abstractions including:

interface RendererOptions<Node, Element> {
  patchProp(
    el: Element,
    key: string,
    prevValue: any,
    nextValue: any
  ): void
  insert(el: Node, parent: Element): void
  createElement(type: string): Element
  // ...
}

function createRenderer<Node, Element>(
  options: RendererOptions<Node, Element>
): Renderer<Element>

This enables Vue3 to be used for rendering targets like mini-programs and Canvas.

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.