A bare-bones implementation of Vue.js-like reactivity
Vue-ish is a minimalistic library that demonstrates the most basic reactivity features in modern front-end JavaScript frameworks such as Vue.js.
After having used Vue.js for a while I became interested in digging deeper to understand how modern JS frameworks do some of the magic that they do. There are a couple of resources online that attempt to explain the Vue source code with varying degrees of granularity. However, with the expception of Evan You's course Advanced Vue.js Features from the Ground Up non of these resources explain the concepts at a fundamental level. What was lacking for me was a self-contained example of reactivity implemented with all the fluff removed. After wading through the source code and reading a few online resources and finally reaching Eureka with Evan's lectures, I decided to create this example for people who are interested in learning about reactivity.
Simply include Vue-ish as a script in your index.html
file. You can grab it from here or use it from a CDN.
<script src="https://cdn.jsdelivr.net/gh/HusamIbrahim/vue-ish@dev/dist/vue-ish.js"></script>
- Arguments:
{Object} object
- Returns: A reactive object
- Usage:
const obj = { foo: 'bar' }
vueish.observe(obj) // makes obj reactive and returns it
- Arguments:
{Function} callback
- Usage:
vueish.autoRun(() => {
// This is the reactive zone! Using any reactive object
// property here will cause the callback function to be
// re-invoked whenever that property's value changes.
})
- Type:
boolean
- Default:
false
- Usage:
// Turns verbose mode on. A message is logged in the console
// when any reactive object property is accessed or set.
vueish.config.verbose = true
// Create a new "h1" element
const h1 = document.createElement('h1')
// Append the element to the DOM
document.body.appendChild(h1)
// Create a reactive state object
const state = vueish.observe({ text: '' })
// Bind the "h1" element's text content to the state object's "text" property
vueish.autoRun(() => { h1.textContent = state.text })
// Modify the state object's "text" property and watch the "h1" element react!
state.text = 'Hello World'
After cloning the repo run:
$ yarn # install project dependencies
# start a development server with hot reloading enabled
$ yarn run start
# build the vue-ish bundle and demo files
$ yarn run build
# run the test suite
$ yarn run test
# run the test suite and generate code coverage reports
$ yarn run test:cover
Reactivity in Vue 2.x depends on the use of Object.defineProperty to make reactive objects (think data
option, for example) by walking over their properties and converting them into getter/setters[π‘]. This allows Vue to intercept object property access/assignment to collect dependencies and notify subscribers(watchers), respectively. It is also why Vue cannot detect object property addition/deletion or direct array member assignment, and why it needs special API methods such as Vue.set
to deal with these use cases[π‘]. Note that this will change in Vue 3.x, which will employ an ES6 Proxy based observation mechanism[π‘].
The same strategy is used in Vue-ish, with two major differences:
- In Vue there's a bookkeeping system wherein watchers keep track of their dependencies and dependencies keep track of their subscribers. This allows Vue to deal with stale dependencies, and is ommitted from Vue-ish for simplicity.
- Vue performs DOM updates asynchronously for performance reasons. It uses a scheduler, which batchs work that needs to be done in the same event loop and flushes the batch queue in the next event loop tick. On the other hand, Vue-ish performs updates synchronously for simplicty.
- How reactivity works in Vue.js
- ES5's Object.defineProperty static method
- Using Jest's custom matchers to write DRY unit tests
- Writing environment dependent webpack configurations from scratch
- Writing scripts to manipulate build artifacts
- CI/CD using GitHub Actions
So you've learned how basic reactivity works in a modern JS framework and you're ready to take on greater challenges. These resources should help you on your journey towards enlightenment π‘
- Advanced Vue.js Features from the Ground Up: This is an excellent course that explains how various aspects of modern JS frameworks are implemented at a fundamental level. From the creator of Vue himself π€
- Read Vue Source Code: A great series that walks through the Vue source code. I found it to be at just the right pace and granularity.
- Vue.js source code: For the truly adventurous π