Reactivity Internals

Preview — 3 of 10 questions

How does Vue 3's reactivity system track dependencies at the implementation level?

javascript
// Simplified Vue 3 reactivity internals
const targetMap = new WeakMap() // WeakMap<target, Map<key, Set<ReactiveEffect>>>

let activeEffect = null

function track(target, key) {
  if (!activeEffect) return
  let depsMap = targetMap.get(target)
  if (!depsMap) targetMap.set(target, depsMap = new Map())
  let dep = depsMap.get(key)
  if (!dep) depsMap.set(key, dep = new Set())
  dep.add(activeEffect)
  activeEffect.deps.add(dep) // Bidirectional tracking for cleanup
}

function trigger(target, key) {
  const depsMap = targetMap.get(target)
  if (!depsMap) return
  const dep = depsMap.get(key)
  dep?.forEach(effect => effect.scheduler ? effect.scheduler() : effect.run())
}

function reactive(target) {
  return new Proxy(target, {
    get(target, key, receiver) {
      track(target, key)
      return Reflect.get(target, key, receiver)
    },
    set(target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver)
      trigger(target, key)
      return result
    }
  })
}
ABy cloning objects on every render and comparing them with deep equality checks
BBy serializing state to JSON and using structural diffing on every state mutation
CUsing Object.defineProperty on each reactive property with getters/setters (same as Vue 2)
DUsing JavaScript Proxy to intercept get/set, with a WeakMap-based dependency tracker mapping targets to effects

How should a Vue plugin that creates global reactive state correctly use effectScope?

javascript
// my-plugin.js
import { effectScope, ref, computed, watch } from 'vue'

let scope
let state

export const myPlugin = {
  install(app) {
    // Detached scope — survives component unmounts
    scope = effectScope(true)

    scope.run(() => {
      state = ref({ count: 0, users: [] })
      const doubleCount = computed(() => state.value.count * 2)

      watch(() => state.value.users.length, (len) => {
        console.log(`User count: ${len}`)
      })
      // All effects above are owned by this scope
    })

    app.provide('myPlugin', {
      state,
      increment: () => state.value.count++
    })

    // Cleanup when the Vue app itself unmounts
    app.onUnmount(() => scope.stop())
  }
}
ACreate one effectScope per component that uses the plugin to keep state isolated
BUse the app's internal effect scope via app._context.provides
CCreate a detached effectScope (with true argument) for the plugin's global state, independent of any component lifecycle
DeffectScope is only for component-level use; plugins should use plain ref at module scope

What is Vue's Custom Renderer API (createRenderer) and what is a valid use case?

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

// Example: Canvas renderer
const { createApp } = createRenderer({
  createElement(type) {
    return new CanvasElement(type) // Platform-specific node
  },
  insert(child, parent, anchor) {
    parent.addChild(child, anchor)
  },
  remove(child) {
    child.parent?.removeChild(child)
  },
  patchProp(el, key, prevValue, nextValue) {
    el.setProp(key, nextValue)
  },
  createText(text) { return new CanvasText(text) },
  createComment(text) { return new CanvasComment(text) },
  setText(node, text) { node.text = text },
  setElementText(el, text) { el.text = text },
  parentNode(node) { return node.parent },
  nextSibling(node) { return node.nextSibling },
  querySelector(selector) { return canvasRoot.querySelector(selector) },
  setScopeId(el, id) { el.scopeId = id },
  cloneNode(el) { return el.clone() },
  insertStaticContent() { return [] }
})

// Now you can use Vue's component model on canvas
createApp(MyCanvasApp).mount(canvasRoot)
AAn API to create Vue renderers targeting non-DOM environments like canvas, WebGL, or native mobile
BAn API to customize how Vue renders standard HTML elements in the browser
CAn API to override the default component render function globally
DAn API specifically for creating server-side renderers (SSR)

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.