marc.dev/blog

Virtual DOM Basics

#vue
#javascript

This is the second part of a series called Create Your Own Vue.js From Scratch, where I teach you how to create the fundamentals of a reactive framework such as Vue.js. In the first part, I described the pieces we need and the road map to follow. If you haven't read it, I suggest you do that before reading this post.

I only have 1 year of professional experience working with Vue.js, but I attended an 8-hour course given by Evan You himself (as part of Vue.js Amsterdam where I learned how Vue.js works on the inside and made me really understand how the "magic" behind the scenes works. This blog series is meant to teach everyone who is interested what I learned on that fantastic workshop, in a comprehensive way.

Roadmap 🚘

  1. Introduction
  2. Virtual DOM basics (this post)
  3. Implementing the virtual DOM & rendering
  4. Building reactivity (coming soon)
  5. Bringing it all together (coming soon)

What is a virtual DOM?

💡 DOM = Document Object Model, the HTML structure of a website 💡 VDOM = Representative copy of that structure

A virtual DOM is a representation of the real DOM into a JavaScript format, where it's easier and cheaper to manipulate it than manipulating the real DOM every time something changes.

It's also useful if you don't want to render the DOm to the browser, but to a string for instance (handy when it comes to server-side rendering).

Virtual nodes

So, the virtual DOM is composed of virtual nodes, which in the example we're going to code will look something like this:

{
    tag: 'div',
    props: {
        class: 'container'
    },
    children: [
        {
            tag: 'h1',
            props: {},
            children: 'Hello World'
        },
        {
            tag: 'p',
            props: {},
            children: 'Lorem ipsum dolor sit amet.'
        }
    ]
}

The example above is the equivalent to this HTML code:

<div class="container">
    <h1>Hello World</h1>
    <p>Lorem ipsum dolor sit amet.</p>
</div>

So all a virtual node is composed of is:

  • An HTML tag as String
  • An Object of properties
  • A list of children than can either be:

    • Another node
    • A text (representing the content)

Virtual DOM skeleton

In our example, we will not build a full-fledged virtual DOM "engine", but enough to understand the basics.

Let's take a look at the coding of the virtual DOM. We will base all future code on the following lines. So, create an HTML-file with the following content:

<div id="app"></app>
<script>

    // Create virtual node
    function h(tag, props, children) {
        // Return the virtual node
    }

    // Mount a virtual node to the DOM
    function mount(vnode, container) {
        // Create the element
        // Set props
        // Handle children
        // Mount to the DOM
    }

    // Unmount a virtual node from the DOM
    function unmount(vnode) {
        // Unmount the virtual node
    }

    // Take 2 vnodes, compare & figure out what's the difference
    function patch(n1, n2) {
        // Case where the nodes are of different tags
        // Case where the nodes are of the same tag
        // Case where the new vnode has string children
        // Case where the new vnode has an array of vnodes
    }

    // Create virtual nodes & render them below this line...
</script>

As you can see, we have five different functions which all do their part to create and render a virtual DOM:

  • h creates a virtual node (but does not mount it yet to the real DOM). I called this h, because that's how it is called in the Vue.js project as well
  • mount will take a given virtual node and mount it to a given container in the real DOM. For the first element, this will be the #app node we created at the very top of the file.
  • unmount will remove the virtual node from it's parent node
  • patch is by far the biggest function we will write for the VDOM. This is, because we have to compare two different nodes and check all the differences in a recursive manner (doing it for all the children recursively).

What's next ⚡️

In part 1, we saw the building parts we'll need for building our own Vue.js-like framework and in this part, we saw the basics of how we are going to build the virtual dom.

In the next chapter, we will then actually implement the complete virtual DOM part.

Stay tuned 😉

If you like my content and updates, your best bet would be to follow me on Twitter. That's where I usually hang out under the handle @_marcba

Original cover photo by Joshua Earle on Unplash, edited by Marc Backes.