new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vue · Guide · all subjects

reactivity-fundamentals

74 notes in this subject, read out of this brain and free to use. This is page 2 of 2.

Active effect pattern enables dependency tracking

An effect is wrapped so that it sets activeEffect = effect before running the update function and sets activeEffect = null after. This enables track() calls during the update to locate and register the current active effect as a subscriber.

Vue components use reactive effects for DOM updates

Each Vue component instance creates a reactive effect to render and update the DOM. This effect automatically re-runs whenever any reactive state it accesses changes, keeping the DOM in sync with state.

Vue 3 Options API implemented on top of Composition API

In Vue 3, the Options API is implemented on top of the Composition API. All property access on the component instance (this) triggers getter/setters for reactivity tracking. Options like watch and computed invoke their Composition API equivalents internally.

Runtime vs compile-time reactivity trade-offs

Vue's reactivity is runtime-based: tracking and triggering occur while code runs in the browser. Runtime reactivity works without a build step and has fewer edge cases, but is constrained by JavaScript syntax limitations, necessitating value containers like refs. Compile-time reactivity (used by Svelte) transforms code during compilation to simulate reactivity, enabling tracking of local variables but requiring a build step.

DebuggerEvent type structure

DebuggerEvent has type: { effect: ReactiveEffect, target: object, type: TrackOpTypes ('get' | 'has' | 'iterate') | TriggerOpTypes ('set' | 'add' | 'delete' | 'clear'), key: any, newValue?: any, oldValue?: any, oldTarget?: Map<any, any> | Set<any> }

Integrating external state systems with shallowRef

To integrate Vue's reactivity with external state management systems, use shallowRef to hold the external state. A shallow ref is only reactive when its .value property is accessed; the inner value is left intact. When external state changes, replace the ref value by assigning to .value to trigger updates.

Immer integration example with Vue

Immer can be integrated with Vue via a composable that uses shallowRef. The pattern: const state = shallowRef(baseState); const update = (updater) => { state.value = produce(state.value, updater) }. This allows using immutable data structures with mutable syntax ergonomics.

XState integration example with Vue

XState can be integrated via a composable using shallowRef. Create a machine, interpret it, subscribe to state transitions to update the ref value, and return both the state ref and a send function for dispatching events.

Signals and refs are equivalent reactivity primitives

Signals (from Solid, Angular, Preact, Qwik) and Vue's refs are the same kind of reactivity primitive: a value container providing dependency tracking on access and side-effect triggering on mutation. This paradigm dates back more than a decade to Knockout observables and Meteor Tracker.

Solid signals API: read/write segregation

Solid's createSignal() exposes signals as a read-only getter and separate setter: const [count, setCount] = createSignal(0). Access value via count(), update via setCount(1). This segregates read and write to prevent unintended mutations unless the setter is explicitly exposed.

Angular signals API: callable with set and update methods

Angular signals are created via signal(0) and work as callables: count() reads the value, count.set(1) sets it, count.update((v) => v + 1) updates based on previous value. This provides a consistent getter interface with separate mutation methods.

Replicating Solid signals pattern in Vue

Solid signals can be replicated in Vue using shallowRef and triggerRef. Export a function that takes initial value and options, creates a shallowRef, returns [getter, setter] tuple where getter returns r.value and setter updates it, optionally triggering manually if equals: false.

Replicating Angular signals pattern in Vue

Angular signals can be replicated in Vue by creating a function that returns a callable shallowRef accessor with .set and .update methods. The callable returns r.value. set(value) assigns r.value. update(updater) assigns r.value = updater(r.value).

API trade-offs: getter-based vs .value-based signals

Getter-based signals (Solid, Angular style) make value access slightly less verbose with () versus .value, but updating is more verbose. No ref-unwrapping means value access is consistent everywhere and raw signals can be passed as component props. Whether to use getter-based or .value-based APIs is subjective and depends on project requirements.

Give your agent this brain