DEV Community

artydev
artydev

Posted on

2

Morphdom and MVU, don't overlook this !

If you haven't read the first article on MVU, I invite you to do so.

Let's continue our adventures with MVU.
This time we will code a very simple counter web component.

Without any ceremony here is the definition of our component.
As you can see, there is very little stuff in it.

class MyCounter extends HTMLElement {
    constructor() {
        super()
        this.state = {
            count: Number(this.getAttribute("init")) || 0
        }
        this.append(myCounter(this))
    }
    update() {
        render(this, myCounter(this))
    }
}

customElements.define('my-counter', MyCounter);
Enter fullscreen mode Exit fullscreen mode

In fact the most 'heavy' part is the implementation of the 'myCounter' MVU component.

Let's see how it is coded :

First let's create some helpers using the m function from MVU

const div = m("div") // div maker
let button = m("button") // button maker 

let styleCounter = `
  display:flex
`
let styleButton = `
  color:red
`
let styleValue = `
  font-size: 24px;
  margin-left: 10px;
  margin-right: 10px;
  user-select: none;
`
const styleButtons = {style:styleButton}
Enter fullscreen mode Exit fullscreen mode

And now the actual implementation of our 'counter' using dom, udom functions from MVU and our previous helpers

function myCounter(elt) {

    let state = elt.state;

    let inc = (incr) => () => {state.count += incr; elt.update()};

    let counter = dom();
    button("inc", styleButtons).onclick = inc(1);
    div(`<div>Counter : ${state.count}</div>`, {style:styleValue});
    button("dec", styleButtons).onclick = inc(-1);
    udom();

    counter.style = styleCounter;

    return counter;
}
Enter fullscreen mode Exit fullscreen mode

You are certainly wondering where is morphdom in this piece of code ?

In fact render is an alias for morphdom.

It's called whenever we click on the buttons through the update method.

Let us now use our newly web component :

<my-counter init="27"></my-counter>
<my-counter init="13"></my-counter>
<my-counter init="9"></my-counter>
Enter fullscreen mode Exit fullscreen mode

I hope you see how esay it is to create a simple web component using MVU functions, no hooks, no bindings, no need to modify directly the elements...

Of course, it is not complete, but for a first try it does the job.

Here is the full code :

import "https://cdn.jsdelivr.net/gh/artydev/mvu@DMLMorph/dist/mvu.es.js";

const div = m("div")
let button = m("button")

let styleCounter = `
  display:flex
`

let styleButton = `
  color:red
`

let styleValue = `
  font-size: 24px;
  margin-left: 10px;
  margin-right: 10px;
  user-select: none;
`

const styleButtons = {style:styleButton}

function myCounter(elt) {
    let state = elt.state;
  let inc = (incr) => () => {state.count += incr; elt.update()};
    let counter = dom();
      button("inc", styleButtons).onclick = inc(1);
      div(`<div>Counter (${state.item}) : ${state.count}</div>`, {style:styleValue});
          button("dec", styleButtons).onclick = inc(-1);
    udom();
  counter.style = styleCounter;
    return counter;
}

class MyCounter extends HTMLElement {
    constructor() {
        super()
        this.state = {
      item: this.getAttribute("item"),
            count: Number(this.getAttribute("init")) || 0
        }
  }
  connectedCallback () {
        this.append(myCounter(this))
    }

    update() {
        render(this, myCounter(this))
    }
}

customElements.define('my-counter', MyCounter);
Enter fullscreen mode Exit fullscreen mode

You can test it here : WebComponentMorphDom

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay