tezvyn:

Vue's Reactivity: JavaScript That Acts Like a Spreadsheet

AI-drafted, machine-checkedSource: vuejs.orgadvanced

Vue's reactivity system makes your data act like a spreadsheet: change a value, and dependent parts of your app update automatically. It works by wrapping your data in special objects. The footgun: reactivity is lost if you replace a whole object.

WHY IT EXISTS Vanilla JavaScript is imperative. If you write c = a + b, and later change a, the value of c does not automatically update. In UI development, this means manually writing code to update the view every time the state changes, which is tedious and error-prone. Vue's reactivity system automates this synchronization, allowing you to declaratively state how the UI should map to the state, and the framework handles the rest.

THE MENTAL MODEL Think of an Excel spreadsheet. If cell A2 has the formula = A0 + A1, it displays their sum. If you change the value in A0, cell A2 automatically recalculates and updates. Vue's reactivity brings this declarative, automatic behavior to your application's state. You define the relationships, and Vue ensures the output (the UI) stays consistent with the inputs (your data).

HOW IT WORKS Vue uses a feature of modern JavaScript called Proxy. When you declare state with ref() or reactive(), Vue doesn't use your original object. Instead, it creates a Proxy that wraps your object. This Proxy acts as a gatekeeper, intercepting any attempts to read or write properties.

First, during the component's initial render, as the template accesses data properties like state.message, the Proxy's get trap is triggered. This allows Vue to register the render function as a "subscriber" to the state.message property, building a dependency graph.

Later, when you change the data, like state.message = 'New message', the Proxy's set trap is triggered. In the set trap, Vue looks up all subscribers for state.message and notifies them to re-run. This causes the component to re-render, displaying the new value in the UI.

WHEN TO USE IT This is the default and primary way to handle state in Vue. Any data that might change and should cause the UI to update must be declared as reactive using ref() for standalone values or reactive() for objects. This is the foundation of building dynamic components.

WHEN NOT TO USE IT There's a small overhead to making data reactive. If you have a large, static list of data that will never change throughout the component's life, you can skip making it reactive to save memory and improve performance. You can use markRaw() to explicitly tell Vue not to convert an object into a proxy.

ONE CANONICAL EXAMPLE Consider this state: const state = reactive({ count: 0 }). The reactive function returns a proxy. Your template might have {{ state.count }}. When this first renders, the proxy's get trap notes that the render function depends on state.count. When some code later runs state.count++, the proxy's set trap is invoked. The setter then triggers a re-render of the component, and the paragraph on the screen updates to show the new count. If state were a plain object, this would not happen.

Read the original → vuejs.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.