Mithril.js

Background

Why another framework?

Dependency Free

Fast!

TodoMVC Benchmark: add 100 items, then delete them

DISCLAIMER

The benchmarks in this talk may be wrong. Many benchmarks are.

If you care about performance, benchmark for yourself for your own use cases!

Small footprint (min+gzip)

Simple API

"Familiar" is not necessarily "simple" but it helps reduce learning curve

Caveat beware

Current version is 0.2.2-rc1

Is considered stable - no idea why pre 1.0

Codebase super small ~ 1200 lines.

Accepted risk when deciding to adopt

You should evaluate on your own

Features

Virtual DOM

Just like HTML, but in Javascript


        |m("div", [
        |  m("a", {href: "http://google.com"}, "Google")
        |])
      

        |<div>
        |    <a href="http://google.com">Google</a>
        |</div>
      

Virtual DOM with CSS syntax style


        |m(".panel.panel-default", [
        |    m(".panel-heading", [
        |       m("h3.panel-title", "Panel title")
        |    ]),
        |    m(".panel-body", [
        |        "Panel content"
        |    ])
        |])
      

         |<div class="panel panel-default">
         |     <div class="panel-heading">
         |         <h3 class="panel-title">Panel title</h3>
         |     </div>
         |     <div class="panel-body">
         |         Panel content
         |     </div>
         |</div>
      

Integrates with other libraries

Provides config attribute that is executed when element is rendered


        |var pulse = function(el) {
        |    Velocity(el, "callout.pulse")
        |}
        |
        |return m("div", { config: pulse }, "Foobar")
      

Getters and Setters


        |//a getter-setter
        |var thing = m.prop( "MacBook" )
        |console.log( thing() ) // "Macbook"
        |
        |thing( "iPhone" )
        |console.log( thing() ) // "iPhone"
      

Why?

Promises


        |function doSomething() {
        |    var deferred  = m.deferred()
        |
        |    setTimeout(function() {
        |        deferred.resolve()
        |    }, 1000)
        |
        |    return deferred.promise
        |}
      

XHR


        |var things = m.request({method: "GET", url: "/things.json"})
        |  .then(list => list.slice(0, 10))
        |  .then(list => list.slice(0, 3))
      

Router

Supports multiple modes:


        |// Index, Hello, Goodbye components defined elsewhere
        |
        |m.route(document.body, "/", {
        |    "/": Index,
        |    "/goodbye": Goodbye,
        |
        |    // Param matcher
        |    "/hello/:name": Hello
        |})
      

Why DOM in JS?

Why HTML

Why not HTML

Functional composition


        |var data = m.prop()
        |
        |// ...
        |
        |m("input", {
        |    oninput: m.withAttr("value", data), // Composition
        |    value: data()
        |})
      

Functional composition


        |var summaryView = function(item) {
        |    return m(".summary", [
        |        m("h3", item.name),
        |        m(".summary-body", item.description)
        |    ])
        |}
        |
        |// ...
        |
        |m(".summaries", projects.map(summaryView))
      

Pick your syntax


        |// Vanilla Javascript
        |m("ul.things", [
        |    m("li", "iPhone"),
        |    m("li", "Macbook"),
        |])
      

      |# Coffescript
      |m "ul.things",
      |  m "li", "iPhone"
      |  m "li", "Macbook"
      

        |// React's JSX
        |<ul class="things">
        |    <li>iPhone</li>
        |    <li>Macbook</li>
        |</ul>
      

Basics

Controllers

Function that accepts a single argument of attributes

Normally faciliate initializing of data for view

Can contain view methods


        |function controller(attrs) {
        |    this.submitForm = function() {
        |       // Do something here
        |    }
        |}
      

Views

Function that accepts the controller and attributes

Must return an array of DOM elements (normally using m but not required)


        |function view(ctrl, attrs) {
        |    return m("h1", "Hello World")
        |}
      

Components

An object that has a view function and optionally a controller function


      |Component = {
      |    /* controller: function(attrs) {}, */
      |
      |    view: function(ctrl, attrs) {}
      |}
      

Mounting

Receive a component and render to DOM


        |Component = {
        |    view: function() {
        |        return m("h1", "Hello World")
        |    }
        |}
        |
        |m.mount(document.body, Component)
      

Taking it further

Taking it further

Demo

Thank You

Github
github.com/adam12
Twitter
@adamrdaniels
Sourcecode
github.com/adam12/mithriljs-devtricks-2016
Demo
JSBin
Mithril
mithril.js.org
Mithril Blog (lots of gems)
lhorie.github.io/mithril-blog
Leo Horie's Talk for some borrowed content
Slides

/