Desk with computer opened and a couple of books

Vue Fundamentals

I love Vue.js. It is easy to learn and efficient to run. It is my favorite frontend framework by far.

I worked a little with React. But I didn’t like the JSX approach. For me, it breaks the concept of Separating the Concerns.

I’m working a little on Angular applications and, wow, it is a lot of files that you need to generate… I’d like to train on it professionally to see if the learning curve is as steep as it looks like to me right now.

If you're interested...

The course is free and available here.

Understanding the Lifecycle Hooks in Vue.js

You can find the diagram of the lifecycle here.

Also, you can find the lifecycle hook list in the official docs to visualize the existing hooks.

Note: this documentation explains the hooks in Vue 3 and the Composition API.

For the Options API, see this documentation explaining the Option API way.

A few comments:

  • it is important to note that in the beforeCreate hook, the reactivity isn’t in place yet. So you can update any data at the moment.
  • on mounted gives access to this.$el, which is the DOM element where the app resides.

In short, the lifecycle order is : beforeCreate > created > beforeMount > mounted > beforeUnmount > unmounted

Double mustaches

We can evaluate an expression in a {{ ... }}.

We cannot declare variables or declare if statements in double mustaches. However, the ternary statement can be used in {{ ifTrue ? "Display this" : "Display that" }}, or the OR operator {{ aStringValue || "Default value" }}.

Dynamic CSS classes

Instead of creating computed to return a string value of a CSS class based on a JavaScript computation, it is a best practice to use dynamic CSS classes.

You can use them to toggle on or off JavaScript expressions that return true or false.

Below, if the item.purchased is true, we toggle strikeout CSS class on the element. The example uses the object syntax.

1
2
3
4
5
6
7
8
        <li
          v-for="item in items"
          :key="item.label"
          class="item"
          :class="{strikeout: item.purchased}"
        >
          {{ item.label }}
        </li>

If you need, you can combine several classes in the array syntax:

1
2
3
4
5
6
7
8
        <li
          v-for="item in items"
          :key="item.label"
          class="item"
          :class="[item.purchased ? 'strikeout': '', item.highlight ? 'highlight': '']"
        >
          {{ item.label }}
        </li>

About computed

A computed is a calculated value and must return a value, contrary to methods that can be void.

It:

  • always returns data
  • shouldn’t change the source data, but only how it is presented. Otherwise, this is a big source of bugs!

The common question : when do you need to use computed over methods?

  • When you change data, use methods.
  • When you change the presentation on the UI, use computed properties.

About props

When you use a prop, make sur to use kebab-case in the template.

For example, this component declares a prop notificationType:

1
2
3
4
5
6
7
8
9
let NotificationMessageComponent = {
  template: "#notification-message-template",
  props: {
    notificationType: {
      type: String,
      default: "info",
    },
  },
};

Using it the camelCase name in the template will make the linter unhappy:

1
<notification-message notificationType="error"></notification-message>

With the following, you’re good to go:

1
<notification-message notification-type="error"></notification-message>

Read the rule in the styleguide:

Prop names should always use camelCase during declaration, but kebab-case in templates and JSX.

We’re simply following the conventions of each language. Within JavaScript, camelCase is more natural. Within HTML, kebab-case is.

The $event object

If you need, the original DOM event is available under $event, that you can pass to the methods that to your v-on or @ directives.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<template>
  <!-- using $event special variable -->
  <button @click="warn('Form cannot be submitted yet.', $event)">Submit</button>

  <!-- using inline arrow function -->
  <button @click="(event) => warn('Form cannot be submitted yet.', event)">
    Submit
  </button>
</template>
<script setup>
  function warn(message, event) {
    // now we have access to the native event
    if (event) {
      event.preventDefault();
    }
    alert(message);
  }
</script>

See the docs.

Differences between v-if and v-show

v-if excludes the DOM element from the DOM at render time.

v-show simply toggle the display CSS property.

Choosing between the two depends on the usecase and the frequency you want to toggle the DOM element.

Generally speaking,

  • v-if has higher toggle costs because the DOM element is not rendered if the condition is false.
  • v-show has higher initial render costs because the DOM element is rendered if not matter the the condition value. A display: none is simply apply by Vue.

So prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtime.

Stay tuned for more about Vue. I’ve a lot of more to share.

Follow me

Thanks for reading this article. Make sure to follow me on X, subscribe to my Substack publication and bookmark my blog to read more in the future.

Credit: Photo by Emile Perron on Unsplash.

Licensed under CC BY-NC-SA 4.0
License GPLv3 | Terms
Built with Hugo
Theme Stack designed by Jimmy