another web journey

Vue at a glance

JavaScript 9 minutes

I don't aim to master all JavaScript frameworks (is it even possible?) but I wanted to get deeper into Vue.js as it looks like it's lightweight, stable and can be implemented progressively. Let's dive in!

What

As W3Schools puts it:

Vue extends HTML attributes with Directives, and binds data to HTML with Expressions.

In this post we'll use the Options API which would be more adequate for progressive implementation. Alternatively you could have your entire application made out of Vue thanks to Composition API.

Basics

  1. Call the distributed JavaScript file: <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> (add prod prior to extension when going into prod)
  2. In body, make room to render the connection: <div id="app"> {{ message }} </div>
  3. Connect elements in script (or dedicated JavaScript file): 
const app = Vue.createApp({
    data() {
      return {
        message: "Hello World!"
      }
    }
  })

app.mount('#app')

Text interpolation

ie what is between a couple of curly moustaches

Could be either text from the app const and/or simple JavaScript expression:

{{ message }}  <p>{{ 'Some text:' + Math.ceil(Math.random()*6) }}</p>

Directives

Directives are special HTML attributes with v-<directiveName>: prefix that connects the HTML attribute it's on with Vue instructions.

v-bind:

Shorthand is :

Makes a connection between an HTML attribute and data in Vue instance.

HTML

<div id="app">
  <div v-bind:class="vueClass">
      <p><a :href="vueURL">{{ urlName }}</a></p>
  </div>
</div>

JavaScript

const app = Vue.createApp({
      data() {
        return {
          urlName: "Go to nowhere",
          vueClass: "pinkBG",
          vueURL: "https://"
        }
      }
    })
    app.mount('#app') 

CSS

.pinkBG {
  background-color: lightpink;
} 

v-if, v-else-if, v-else

These directives are used for conditional rendering. If true: it renders, if false: it does not render.

HTML in <div="app">

<p v-if="daytime == 'morning'">Good morning!</p>
<p v-else-if="daytime.includes('eve')">Good evening!</p>
<p v-else>Hello!</p> 

JavaScript

  const app = Vue.createApp({
   data() {
    return {
      daytime: "evening"
    }
   }
  })
  app.mount('#app')

v-show

Directive to switch display CSS value depending on a condition.

HTML in <div="app">

 <p v-show="isVisible">Hide me</p>

JavaScript

  const app = Vue.createApp({
   data() {
    return {
      isVisible: true
    }
   }
  })
  app.mount('#app')

Note: with this directive, the element exists in the DOM, it's just hidden/showed, so it's quite easy for the browser to manage.

v-for

Use a Vue for-loop to create several elements easily.

HTML in <div="app">

<ul>
  <li v-for="(elem, index) in todoList">{{ index }} : {{ elem }}</li>
</ul>

<p v-for="x in somebodyLikes">{{ x.name }} likes {{ x.food }}</p>

JavaScript

 const app = Vue.createApp({
   data() {
    return {
      todoList: ["be kind to yourself", "be kind to others", "enjoy present moment"],
      somebodyLikes: [
        { name: "Julie", food: "Crêpes" },
        { name: "Marie", food: "Flan"}
      ]
    }
   }
  })
  app.mount('#app')

Events

Listen to an event via v-on:<eventName> directive. For instance

HTML in <div="app">

<p>{{ count }}</p>
<p>{{ xPos }} {{ yPos }}</p>
<button v-on:click="count++">Add 1</button>
<button v-on:click="add(5)">Add 5</button>
<button v-on:click="reset">Reset</button>

JavaScript

 const app = Vue.createApp({
   data() {
    return {
        count: 0,
        xPos: 0,
        yPos: 0 
    }
   },
   methods: {
      add(number) {
             this.count += number
      },
      reset(event) {
      this.count = 0,
      this.xPos = event.offsetX,
      this.yPos = event.offsetY
    }
  } 
  })
  app.mount('#app')

Shorthand for v-on is @

Note that you can store functions belonging to a Vue instance in the "methods" property. Inside, we need to use this. prefix to refer to a data property. You can access event information via the event object (if you need the event object and an argument, user following syntax: myFunction($event, myArg)).

Form Input binding

Use the v-model directive for synchronizing the form input state with JavaScript state. For instance:

HTML

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

Template Refs

Use the ref attribute to an element to access it easily just like you would do with an id attribute. It goes into being exposed on this.$refs

HTML

<input ref="input">

JavaScript

const app = Vue.createApp({
     mounted() {
    this.$refs.input.focus()
    }
  })
app.mount('#app')