Profile picture of Marc Backes (very handsome) Profile picture of Marc Backes (very handsome)
Marc Backes

Virtual DOM Basics

March 16, 2020 · by Marc Backes
Profile picture of Marc Backes (very handsome) Profile picture of Marc Backes (very handsome)
Virtual DOM Basics Virtual DOM Basics
I
n this second part of the series, we look more closely to the virtual DOM and learn some basics about it. We also prepare some things to get ready for implementing the VDOM engine.

This post 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. To follow this blog post, I suggest you first read the other parts of the series.

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.