Understanding Reactivity in Vue.js


In the realm of Front-end development, “Reactivity” is a fundamental concept widely utilized, yet often not fully comprehended. In the context of Front-end frameworks, reactivity in Vue.js refers to the automatic reflection of changes in the application state onto the Document Object Model (DOM).

Reactivity in Vue.js

Reactivity is an integral part of Vue.js, seamlessly integrated into the framework. To illustrate, consider a simple example of reactivity using two-way binding (via v-model):

new Vue({
el: '#app',
data: {
message: ''

In this Vue.js example, any alteration in the data model layer is instantly mirrored in the view layer:

<!-- Vue.js Template -->
<input type="text" v-model="message">
{{ message }}

A Vanilla JavaScript Comparison

For those familiar with Vue.js, this reactivity behavior is expected. However, when attempting to replicate this in vanilla JavaScript, disparities become evident. In the absence of Vue.js, standard JavaScript fails to exhibit the same reactivity. Consider the following example mimicking the Vue.js reactivity example in vanilla JS.

Vue.js Reactivity System

To comprehend this discrepancy, let’s delve into the underlying reactivity system of Vue.js.

First Render

During the initial rendering, when a data property is accessed (referred to as “touched”), its corresponding getter function is invoked.


Subsequently, a watcher is triggered, responsible for adding the data property as a dependency and invoking the component render function.

Component Render Function

Vue’s component render function, though not simplistic in reality, essentially returns the Virtual DOM Tree with updated data properties, subsequently displayed in the view.

Changes in Data

The core of Vue.js reactivity lies in handling changes to data properties. When a change occurs in a data property marked as a dependency, its setter function is invoked, notifying the watcher. The watcher, in turn, invokes the component render function, updating the view with the modified data property.

Recreating Vue.js Reactivity in Vanilla JavaScript

Now, let’s embark on recreating Vue.js reactivity in vanilla JavaScript. To comprehend this process thoroughly, we’ll break it down into building blocks.

Building Blocks of Recreated Reactivity System

1. Data Model

Begin by establishing a data model, mirroring the structure of the Vue.js example:

let data = {
message: ''

2. Target Function

Introduce a global variable ‘target’ to record target functions associated with data properties:

let target = null;

3. Dependency Class

Create a Dependency class to manage the storage of target functions for each data property:

class Dep {
constructor() {
this.subscribers = [];
depend() {
if (target && !this.subscribers.includes(target)) {
notify() {
this.subscribers.forEach((sub) => sub());

4. Tracking Changes

Utilize getters and setters, along with Object.defineProperty(), to track changes in data properties and trigger the corresponding target functions:

Object.keys(data).forEach((key) => {
let internalValue = data[key];
const dep = new Dep();
Object.defineProperty(data, key, {
get() {
return internalValue;
set(newVal) {
internalValue = newVal;

5. Watchers

Introduce a watcher function to encapsulate code that needs to run when a data property’s value changes:

let watcher = function (func) {
target = func;
target = null;


By assembling these building blocks, we have successfully recreated the Vue.js reactivity system in vanilla JavaScript. This comprehensive approach provides a deep understanding of reactivity and its implementation in both Vue.js and vanilla JavaScript.

© 2013 - 2024 Foreignerds. All Rights Reserved