Skip to content

Instantly share code, notes, and snippets.

@lazywithclass
Last active July 26, 2017 10:07
Show Gist options
  • Save lazywithclass/e4381f4499d8595e92d5f15ac3f52907 to your computer and use it in GitHub Desktop.
Save lazywithclass/e4381f4499d8595e92d5f15ac3f52907 to your computer and use it in GitHub Desktop.
Learning Vue.js

Learning Vue.js - lazyblog

A lot of time has passed since I willingly wanted to learn a frontend JS framework, I am doing it again because

  • Vue's docs seems to be detailed enough
  • there's a nice and easy way to start
  • I've used it for a take home assignment as part of a job interview and loved how it all came together easily and almost painless
  • enriches HTML the Angular.js way, so that's something I already know
  • I might have a project for a web app

No arrow function

On an instance property or callback, this was something I faced while coding the take home assignment, for example it is true for

I was baffled that you could do

var Component = Vue.extend({
  data: function () {
    return 42
})

and not

var Component = Vue.extend({
  data: () => 42

the docs explain why

The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.myProp will be undefined.

.vue components

I like the idea of having .vue components, that allows to define a template along with CSS, and some JS code to define some behaviour: I feel it handy to have everything there, so you don't have to jump around 3 files.

I particularly appreciated this example:

<template>
  <div id="counter-event-example">
    <p>{{ total }}</p>
    <button-counter v-on:increment="incrementTotal"></button-counter>
    <button-counter v-on:increment="incrementTotal"></button-counter>
  </div>
</template>
<script>
  Vue.component('button-counter', {
    template: '<button v-on:click="increment">{{ counter }}</button>',
    data: function () { return { counter: 0 } },
    methods: {
      increment: function () {
        this.counter += 1
        this.$emit('increment')
      }
    },
  })
  new Vue({
    el: '#counter-event-example',
    data: {
      total: 0
    },
    methods: {
      incrementTotal: function () { this.total += 1 }
    }
  })
</script>

It shows how easily you can communicate between components, here a component emits increment everytime a one of the buttons is clicked, updating counter which is the global state in this example.

It's important to note that data flows from parent to child, while the way to notify the parent is to emit an event. I think they did it this way to achieve module separation. In case two components need to communicate with each other you could use Vue as a bus

var bus = new Vue()
// in component A's method
bus.$emit('id-selected', 1)
// in component B's created hook
bus.$on('id-selected', function (id) {
  // ...
})

pretty convenient. There's a more complex Flux-like state management but I think for now I'm happy like this.

Also, to finish, dynamic components!

Watch and computed

AFAIK watch is for async operations, while computed is useful since it caches the result so it could be returned without computing again, watch on the other hand gives more freedom.

Lifecycle

Worth a mention is the lifecycle diagram, so useful when you need to understand when to do things.

Testing

This is all good but I've been wondering all the time "how do I test this?" The fact that "Unit Testing" has been placed in the "Advanced" section of the guide doesn't appeal to me as something easy to do, hopefully I will be proven wrong.

Overall

I am impressed by how easy is to pick it up, the tooling is there and there's quite a few things to learn but it's a smooth journey, I don't think I will go back to any other framework, also because whenever you have an error in your code it's really easy to spot the problem.

Also, make sure to install the browser plugin, it helps a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment