Vue.js
Past, Present
and Future

(Or: A Series of Fortunate Nerd Snipes)

Alex Riviere

  • Senior Frontend Developer
  • Atlanta Vue.js Co-Organizer
  • Handwritten Font Connoisseur

Nerd Sniping

[[Hat Guy is sitting on a chair, the Normal Guy is standing next to him. Across the street another man is coming from a building.]]\nHat Guy: There's a certain type of brain that's easily disabled. If you show it an interesting problem, it involuntarily drops everything else to work on it.\n[[The man across the street is about to enter a crosswalk]]\nHat Guy: This has led me to invent a new sport: nerd sniping. See that physicist crossing the road?\n[[Hat Guy holds up a sign]]\nHat Guy: HEY!\n[[There is an image of a grid with resistors on every connection, two nodes a knight's move apart are marked with red circles.]]\nThe sign reads: On this infinite grid of ideal one-ohm resistors, what's the equivalent resistance between the two marked nodes?\nPhysicist on the street: It's... Hmm. Interesting. Maybe if you start with... No. Wait. Hmm... You could--\n[[A truck is zooming past, apparently where the physicist just stood]]\n<<FOOOOM>>\nNormal guy: I will have not part in this.\nHat Guy: C'mon, make a sign. It's fun! Physicists are two points, mathematicians three.\n{{Alt: I first saw this problem on the Google Labs Aptitude Test.  A professor and I filled a blackboard without getting anywhere.  Have fun.}}

Nerd Sniping

[[Hat Guy is sitting on a chair, the Normal Guy is standing next to him. Across the street another man is coming from a building.]]\nHat Guy: There's a certain type of brain that's easily disabled. If you show it an interesting problem, it involuntarily drops everything else to work on it.\n[[The man across the street is about to enter a crosswalk]]\nHat Guy: This has led me to invent a new sport: nerd sniping. See that physicist crossing the road?\n[[Hat Guy holds up a sign]]\nHat Guy: HEY!\n[[There is an image of a grid with resistors on every connection, two nodes a knight's move apart are marked with red circles.]]\nThe sign reads: On this infinite grid of ideal one-ohm resistors, what's the equivalent resistance between the two marked nodes?\nPhysicist on the street: It's... Hmm. Interesting. Maybe if you start with... No. Wait. Hmm... You could--\n[[A truck is zooming past, apparently where the physicist just stood]]\n<<FOOOOM>>\nNormal guy: I will have not part in this.\nHat Guy: C'mon, make a sign. It's fun! Physicists are two points, mathematicians three.\n{{Alt: I first saw this problem on the Google Labs Aptitude Test.  A professor and I filled a blackboard without getting anywhere.  Have fun.}}

October 26th, 2018

React Hooks is demoed publicly for the first time

A screen capture of Dan Abramov at React Conf 2018 demoing React Hooks for the first time

October 27th, 2018

Screenshot of a tweet from Evan You dated October 27th, 2018 at 12:38am, "Okay I can't really help myself... use hooks in Vue (via userland lib in under 100 LOC): (link to CodeSandbox)"

CodeSandbox

June 7th, 2019

Vue RFC #42 is proposed for
"Function-based Component API"

This is what later becomes known as

"Composition API"

Vue 3.0.0

(Released 2020-09-18)

  • New Reactivity System using Proxy Objects

  • Composition API and setup method

  • Removal of filters

Composition API

Options API

<script>
export default {
  data(){
    return {
     count: 0,
    }
  },
  methods:{
    increment(){
      this.count++;
    }
  },
}
</script>
<template>
  <button type="button" @click="increment">
    the count is {{count}}
  </button>
</template>
<script>
import {ref} from 'vue';
  
export default {
  setup(){
    const count = ref(0);
    const increment = ()=>count.value++

    return{
      count,
      increment,
    }
  }
}
</script>
<template>
  <button type="button" @click="increment">
    the count is {{count}}
  </button>
</template>

Vite 1.0.0-rc.13

(Released 2020-11-25)

  • Core team realized with minor changes could be more than a vue build tool
  • Ditched v1, and started on v2

Vite 2.0.0

(Released 2021-02-16)

  • Supports multiple frameworks
  • Super fast dev experience
  • Builds with rollup
A callback to the XKCD Nerd Sniping Comic where the black hat guy holds up a sign and shouts hey! but the sign instead says "Alpine.js is smaller than Vue3"
A tweet from evan you that just has an eye emoji with an image displaying some code that is using a package called petite-vue

Petite-vue

  • Only ~6kb
  • Vue-compatible template syntax
  • DOM-based, mutates in place
  • Driven by @vue/reactivity

Vue 3.2.0

(Released 2021-08-09)

script setup syntax

 

And more...

https://blog.vuejs.org/posts/vue-3-2

Composition API

<script>
import {ref} from 'vue';
  
export default {
  setup(){
    const count = ref(0);
    const increment = ()=>count.value++

    return{
      count,
      increment,
    }
  }
}
</script>
<template>
  <button type="button" @click="increment">
    the count is {{count}}
  </button>
</template>

Script Setup

<script setup>
import {ref} from 'vue';

const count = ref(0);
const increment = ()=>count.value++

</script>
<template>
  <button type="button" @click="increment">
    the count is {{count}}
  </button>
</template>

Vue 3.3.0

(Released 2023-05-11)

  • Better TypeScript support
  • <script setup> generics support
  • Generally, a lot of DX improvements.

But what does the future hold?

"Vapor" Mode 

  • Opt in mode to remove VDOM
  • Can be done at either component level or app level
  • only works with <script setup>
  • will be compatible with vdom components

"Normal" Mode 

MyCounter.vue
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <div>
    <button @click="count++">
      {{ count }}
    </button>
  </div>
</template>
MyCounter.js
import { toDisplayString as _toDisplayString, 
        createElementVNode as _createElementVNode, 
        openBlock as _openBlock, 
        createElementBlock as _createElementBlock } from "vue"

import { ref } from 'vue'

const __sfc__ = {
  __name: 'App',
  setup(__props) {

    const count = ref(0)
    
    return (_ctx, _cache) => {
      return (_openBlock(), _createElementBlock("div", null, [
        _createElementVNode("button", {
          onClick: _cache[0] || (_cache[0] = $event => (count.value++))
        }, _toDisplayString(count.value), 1 /* TEXT */)
      ]))
    }
  }
}
__sfc__.__file = "src/App.vue"
export default __sfc__

"Vapor" Mode 

MyCounter.vapor.vue
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <div>
    <button @click="count++">
      {{ count }}
    </button>
  </div>
</template>
MyCounter.vapor.js
import { ref, effect } from "vue"

import { template, on, setText } from 'vue/vapor'

const t0 = template('<div><button>')

export default () => {
  const count = ref(0)
  
  let div = t0()
  let button = div.firstChild
  let _button_text
  effect(()=>{
    setText(button, _button_text, count.value)
  })
  on(button, 'click', () => count.value++)
  return div
}

Wider eco-system

  • Nuxt - Has several projects that help other frameworks through the unjs project
  • Astro and Iles - Opt in client side js frameworks. Won't ship JS unless you specify it.
  • Volar - changed from being vue editor tooling to an agnostic editor tooling framework

Thank YOU!

Questions?

Slides:

https://slides.com/fimion/hackbuddy-2023-08

 

Twitter: @fimion - Blog: Alex.Party - Github: fimion