The Progressive JavaScript Framework

Meir Kriheli / @mkriheli

PyWeb-IL 69, Oct 2, 2017

Short History

  • Created by Evan You
  • Worked at Google
  • Liked some concepts in Angular
  • Not the complexity
"I figured, what if I could just extract the part that I really liked about Angular and build something really lightweight without all the extra concepts involved?"
  • First released February 2014
  • Made a splash at Reddit, HN, etc.
  • Successful in China
  • Version 2.0 Released at April 2016
  • Made popular by Laravel community
  • Adopted by quote few project, e.g. GitLab
  • Successful open source product
  • Stars, community, closed bugs
  • Evan is self sustained via Patreon


  • Less opinionated
  • Incrementally adoptable architecture
  • Can start simple - enhance a page
  • e.g.: Embed into Django or Jinja template
  • Up to full blown SPA


  • Performance and size
  • Focus on making UI devel more approachable
  • Learning from other frameworks pros and cons
  • Declarative rendering
  • Component Composition

Advanced Features

Officially maintained!

  • CLI starter (webpack, browserify, ES2015, scss)
  • Single file components
  • Routing
  • State management

Good, easy to follow documentation


Basic Vue App

<script src=""></script>

<div id="app">
  <p>{{ message }}</p>

  new Vue({
    el: '#app', // <- Element to mount the app on
    data: {     // <- Reactive data
      message: 'Hello Vue.js!'

Bound HTML attributes

For reactive HTML attributes use v-bind

<img src="{{ imgURL }}"> <-- Won't work -->
<img v-bind:src="imgURL"> <-- That's it -->
or shorthand syntax:

<img :src="imgURL"> <-- Nice -->


Use v-on

<button v-on:click="message = 'yo'">Change message</button>
or shorthand syntax:

<button @click="message = 'yo'">Change message</button>

Event Modifiers

Control DOM events without writing code. Some modifiers from the docs:

<!-- the click event's propagation will be stopped -->
<a v-on:click.stop="doThis"></a>

<!-- the submit event will no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- modifiers can be chained -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- just the modifier -->
<form v-on:submit.prevent></form>

For key and mouse events too

See the docs

<!-- only call vm.submit() when the keyCode is 13 -->
<input v-on:keyup.enter="submit">

<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>


<div id="app">
  <p>{{ message }}</p>
  <button @click="changeMessage"></button>

  new Vue({
    el: '#app', // <- Element to mount the app on
    data: {     // <- Reactive data
      message: 'Hello Vue.js!'
    methods: {
      changeMessage: function() {
        this.message = 'Yo';


Note the usage of this and the way the template uses data and methods without their keys.

Vue proxies them for us, some with getter/setters to track data changes. It also handles binding this.

Proxying Caveats

Sometimes Vue can't detect property changes, e.g.:

arr[10] = 12;

or when adding keys dynamically to data.

In those case use Vue.set:

Vue.set(arr, 10, 12);

See also Reactivity in Depth.

Computed properties

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')

Unlike methods, computed properties are cached based on their dependencies.

Hammer Fiddle time

Enough theory, let's have some fun with JSFiddle.

Control Flow Directives


  • v-if
  • v-else

Add/Remove items from DOM:

<div v-if="Math.random() > 0.5">
  Now you see me
<div v-else>
  Now you don't


Since 2.1.0

<div v-if="type === 'A'">
<div v-else-if="type === 'B'">
<div v-else-if="type === 'C'">
<div v-else>
  Not A/B/C


Always rendered in DOM, toggles display style.

List rendering: v-for

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}

<div v-for="(value, key) in object">
  {{ key }}: {{ value }}

Form Inputs

Two way data binding with v-model:

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

Modifiers: .lazy, .number, .trim.

Let's look at the docs.


Pretty much like the Vue instance.

Vue.component('panel', {  // registered globally
  props: ['message'], // declare the props the component accepts
  data: function() { // Must, otherwise will be shared by instances
    return {
      counter: 0
  template: '<div class="panel">{{ message }}</div>'

<panel message="hello!"></panel>

Data Flow

  • Top-to-Bottom (parent to child)
  • Use this.$emit() to parent changes.
  • Use a Vue() instance as event bus for cross component notifications.


Follows HTML template standards.

Like Angular 1's transclude.

<-- component template -->
  <h2>I'm the child title</h2>
    This will only be displayed if there is no content

<!-- parent template -->
  <h1>I'm the parent title</h1>
    <p>This is some original content</p>
    <p>Will be displayed inside the slot</p>

CLI detour

Play with build tools, single file components, browser dev tools, and ES2015 goodness.

$ # install vue-cli
$ npm install --global vue-cli
$ # create a new project using the "webpack" template
$ vue init webpack my-project
# install dependencies and go!
$ cd my-project
$ npm install
$ npm run dev

Play time

Rich Ecosystem

  • Quasar Framework - Responsive, PWAs, hybrid mobile apps
  • Weex - Native mobile apps
  • Buefy - Lightweight UI components
  • NUXT.js - Server side rendering and static generation.

Awesome Vue.js - A curated list of Vue.js related things. .

I know kung fu

Currently @Vast Data

We're hiring: Python, C++, QA and Automation


Thank you